Task 1.纸盒子(box.pas/box.c/box.cpp)
【题目描述】
Mcx是一个有轻度洁癖的小朋友。有一天,当他沉溺于数学卷子难以自拔的时候,恍惚间想起在自己当初学习概率的时候准备的一堆橡皮还杂乱地堆在自习室里。这显然是他无法容忍的。于是他决定做一个体积为V(V=abc)的纸盒子,以便能整齐的摆放它们。为了简单起见,这个纸盒子的长、宽、高均为正整数。当然了,Mcx是一个以勤俭闻名的小朋友,因此他想知道,这个纸盒子的表面积(S=2ab+2ac+2bc)的最小值是多少呢?
【题目输入】
仅一行,为一个正整数V,表示纸盒子的体积。
【题目输出】
仅一行,为一个正整数S,表示纸盒子的最小表面积。
【样例输入】
17
【样例输出】
70
【样例解释】
对于体积为17的盒子只有一种制作方法就是长1宽1高17(这里我们可以认为长,宽,高是等价的),于是它的最小表面积就是2*1*17+2*1*17+2*1*1 = 70
【数据范围】
30%数据满足V<=1000
100%数据满足V<=10^9
【题解】
刚开始做这道题的时候看得出是道数学题,但身为一名数学蒟蒻就是想不出来数学方法,考完后看题解才恍然大悟。
首先要枚举长宽高,但根据数据范围直接枚举会炸的很惨(比如我)。假定a<=b<=c,那么a的最小值为1,最大值为三次根号下V,于是就从1枚举到三次根号下V即可。对于b,由于a已经枚举出,b的最小值就为a,最大值为根号V,于是就从a枚举到根号V即可。对于C,由于a和b已经枚举出,用V/a/b即可。
每枚举完一组a、b、c,先判断a、b、c能不能合法构成改体积的纸盒,即能否被体积除尽。若合法,则记录所有结果中的最小值。输出最小值即可。
AC代码:
1 #include <cstdio> 2 #include <cmath> 3 using namespace std; 4 long long N,minn=1e9; 5 int main(){ 6 scanf("%lld",&N); 7 for(int i=1;i<=sqrt(N);++i) //并不知道三次根号怎么写于是偷懒写了个根号。。 8 for(int j=i;j<=sqrt(N/i);++j) 9 if(!(N%i)&&!(N%j)&&!(N%(N/i/j))){ 10 long long t=2*(i*j+i*(N/i/j)+j*(N/i/j)); 11 if(t<minn) minn=t; 12 } 13 printf("%lld",minn); 14 return 0; 15 }