博客
关于我
已知矩形体积,求解最小表面积(优化算法)
阅读量:345 次
发布时间:2019-03-04

本文共 1959 字,大约阅读时间需要 6 分钟。

题是51nod上的 3330 Minecraft

输入一个n,n<=1e9,n是小方块个数,可以相当于已知矩形体积,求解最小表面积的长宽高为整数的解。

首先因为n的范围很大,不能用三重循环的做法,就是分别遍历长宽高,然后满足条件算出表面积维护最小值。
最简单的优化是把三重循环变成二重循环,参考poj 2363 ,相当于用体积公式去掉一重循环,已知长宽可以由V=abc得a=V/(b*c),然后同上,满足条件算出表面积维护最小值。

接下来就是能ac的思路了,第一步先求出n的所有质因数,就是不断除以2,除到不能除为止看能不能除以3、5、7…
第二步是把这些质因数存到动态数组里,分为五种情况,一是动态数组里没有值,这种情况只能是n=1,由表面积计算公式得s=6,输出即可;二是动态数组有唯一值,三是动态数组有唯二值,四是动态数组有唯三值,把值赋给矩形的边,剩下的补1,由表面积公式求出即可;五是动态数组中的值大于三个,由规律可知最大的质因数一定是矩形的其中一个边,然后不断改变矩形的其它两边(由不等式定理知三边最接近时表面积最小)(可理解为三边相减的绝对值最小的时候表面积最小)然后通过更新两条边的值算出绝对值相减最小的时候并记录三条边的值。ans为求出的最小表面积的结果。

#include<iostream>#include<set>#include<queue>#include<cmath>#include<stack>#include<vector>#include<string>#include<cstring>#include<cstdio>#include<map>#include<algorithm>using namespace std;const int maxn=1e6+5;typedef long long ll;vector<ll> ve;ll ans=0x3f3f3f3f;int judge(ll a,ll b,ll c){
       if(b<c){
           ll temp=b;        b=c;        c=temp;    }    return (a-c)+(a-b)+(b-c);}void solve(){
       ll a,b,c=1;    ll min=0x3f3f3f3f;//三边维护值最小(绝对值)    a=ve[ve.size()-1];//一定是个大质因数,它不变,但是三边维护要用它    b=ve[ve.size()-2];    for(int i=0;i<ve.size()-2;i++){
           c*=ve[i];    }    ll bb=b,cc=c;    int t=0;    while(true){
           if(min>judge(a,b,c)){
               min=judge(a,b,c);            bb=b;            cc=c;        }        b*=ve[t];        c/=ve[t];        if(t==ve.size()-3) break;        else t++;    }    ans=2*(a*bb+a*cc+bb*cc);}int main(){
       ll n;    cin>>n;    while(n%2==0){
           ve.push_back(2);        n/=2;    }    for(int i=3;i<=sqrt(n*1.0);i+=2){
           while(n%i==0){
               ve.push_back(i);            n/=i;        }    }    if(n>2){
           ve.push_back(n);    }    int len=ve.size();    if(len==0) ans=6;    else if(len==1) ans=ve[0]*4+2;    else if(len==2) ans=2*(ve[0]*ve[1]+ve[0]+ve[1]);    else if(len==3) ans=2*(ve[0]*ve[1]+ve[0]*ve[2]+ve[1]*ve[2]);    else{
           //找到三个边,三边维护绝对值差最小        solve();    }    cout<<ans<<endl;    return 0;}

转载地址:http://chdr.baihongyu.com/

你可能感兴趣的文章
深入理解数组指针与指针数组的区别
查看>>
iOS客户端与PHP服务端的简单交互
查看>>
Python的异常处理
查看>>
Kubernetes(k8s)的调度器详细介绍
查看>>
Linux的网络参数设置
查看>>
紫书——蛇形填数
查看>>
吐泡泡(栈)
查看>>
刷题计划1——poj1753
查看>>
第一场
查看>>
蓝桥杯备战——刷题(2019)
查看>>
ArcMap|栅格计算器报错
查看>>
《小石潭记》古文鉴赏
查看>>
Matlab中有关字符串数组的常见问题解答
查看>>
未定义的变量“py”或函数“py.command”
查看>>
我们,都一样......(句句入心)
查看>>
总结了一下c/c++函数和变量的命名规则
查看>>
关于构造函数内调用虚函数的问题
查看>>
最短路径问题—Dijkstra算法
查看>>
求二叉树的深度
查看>>
录音功能
查看>>