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

本文共 1947 字,大约阅读时间需要 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/

你可能感兴趣的文章
LeetCode11_二叉树的层序遍历_BFS迭代、DFS递归、拓展BFS的使用场景
查看>>
Tomcat启动过程连接部分-(下)
查看>>
JVM篇-结合源码分析垃圾收集器的类型
查看>>
STM32F407单片机ADC采样定时器触发事件分布
查看>>
LWIP协议socket通信设置发送接收超时等待时间
查看>>
RT -Thread Studio开发环境下使用W5500做TCP客户端
查看>>
Warning: The core is locked up的解决办法
查看>>
奔涌吧 后浪!!! 哔哩哔哩 何冰
查看>>
【JVM系列】JDK 内置工具
查看>>
JAVA 基础与进阶系列索引 -- JDK 源码学习系列 -- 并发
查看>>
网络编程系列索引 -- Linux 网络编程索引
查看>>
网络编程系列索引 -- JAVA 网络编程系列
查看>>
【JDK源码分析系列】ArrayBlockingQueue源码分析
查看>>
【网络通信 -- 直播】音视频常见封装格式 -- MEPG2 TS
查看>>
【网络通信 -- 直播】音视频常见封装格式 -- FLV
查看>>
【C/C++基础进阶系列】C/C++ 对象模型 -- 类基础知识总结(三)
查看>>
【C/C++基础进阶系列】C/C++ 对象模型 -- 对象语义
查看>>
【Linux网络编程】使用eclipse调试libevent和开发libevent应用程序
查看>>
基于FPGA的HDMI信号采样原理
查看>>
Spring 与使用STOMP消息
查看>>