
已知矩形体积,求解最小表面积(优化算法)
发布日期:2021-05-07 16:48:58
浏览次数:12
分类:原创文章
本文共 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;}
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年03月25日 00时28分33秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
剑指offer JZ21 栈的压入弹出序列
2019-03-04
剑指offer JZ31 整数中1出现的次数
2019-03-04
实现基于scrapy框架的天气预报爬虫hengYangSpaider @572311文
2019-03-04
maven打包指定名称并去除jar-with-dependencies后缀
2019-03-04
Netty4服务端入门代码示例
2019-03-04
操作系统前传第六课--开发中的辅助工具
2019-03-04
Linux系统编程44 信号 - 信号的响应过程分析!!!
2019-03-04
VL53L0x TOF激光测距的 stm32 HAL库驱动代码
2019-03-04
怎么玩LOG4J
2019-03-04
Oracle创建用户,分配表空间
2019-03-04
自定义标签(JSP2.0)简单标签
2019-03-04
MyBatis自定义类型转换器
2019-03-04
机器学习(湖北师范大学教程)-极大似然估计算法
2019-03-04
读《红楼梦》有感
2019-03-04
【C# 重构】—参数化查询, 需要参数,但未提供该参数
2019-03-04
决策树(二)—— ID3和C4.5
2019-03-04
MySQL~教你满分回答什么是数据库索引? 索引的数据结构是什么? 什么是事务?
2019-03-04
操作系统~进程的状态、转换、控制
2019-03-04
操作系统~线程概念以及多线程模型
2019-03-04
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,时间复杂度均为O(1))
2019-03-04