对应POJ题目:点击打开链接
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 46584 | Accepted: 15752 |
Description
Input
Output
Sample Input
0 0 4 0 0 1 7 5 1 0 0 0 0 0 0 0 0 0
Sample Output
2 1
题意:
装箱问题
问题描述
一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个
型号,他们的长宽分别为 1*1, 2*2, 3*3, 4*4, 5*5, 6*6. 这些产品通常使用一个 6*6*h
的长方体包裹包装然后邮寄给客户。因为邮费很贵,所以工厂要想方设法的减小每个订单运送时的
包裹数量。他们很需要有一个好的程序帮他们解决这个问题从而节省费用。现在这个程序由
你来设计。
输入数据
输入文件包括几行,每一行代表一个订单。每个订单里的一行包括六个整数,中间用空
格隔开,分别为 1*1 至6*6 这六种产品的数量。输入文件将以 6 个0 组成的一行结尾。
输出要求
除了输入的最后一行6 个0 以外,输入文件里每一行对应着输出文件的一行,每一行输
出一个整数代表对应的订单所需的最小包裹数。
输入样例
0 0 4 0 0 1
7 5 1 0 0 0
0 0 0 0 0 0
输出样例
2
1
思路:
高度无需考虑,只考虑面积就行。假设输入a1, a2, a3, a4, a5, a6
从面积最大的开始处理,可知,对于6*6大小的箱子,6*6的物品会霸占一个箱子;5*5的物品会余下11个能装1*1物品的空间;4*4的物品会余下20个1*1的空间,可以放2*2和1*1的物品;对于3*3的物品,所需的箱子数就是(a3 + 3) / 4(即是a3除以4向上取整),然后余数为0就刚好放完;为1就剩下27个1*1的空间,为2就剩下18个1*1的空间,为3就剩下9个1*1的空间;然后把2*2和1*1的物品尽可能多地往已用的箱子里面塞;多出的向上取整。
这题用到几个技巧可以缩短代码量,做完后观看网上的代码,好短~
本人代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
int a1, a2, a3, a4, a5, a6;
int i, ans;
int b, r, c, p, all;
//freopen("in.txt", "r", stdin);
while(scanf("%d%d%d%d%d%d", &a1, &a2, &a3, &a4, &a5, &a6) == 6)
{
if(0 == a1 + a2 + a3 + a4 + a5 + a6) break;
ans = a6 + a5 + a4;
c = 0;
b = 5 * a4;
ans += (a3 + 3) / 4;
r = a3 % 4;
if(1 == r) c = 5;
else if(2 == r) c = 3;
else if(3 == r) c = 1;
b += c;
p = 0;
if(r) p = 36 - 9 * r;
all = 11 * a5 + 20 * a4 + p;
//if(b > a2){all -= 4 * (b - a2); a2 = 0;}
if(b > a2){all -= 4 * a2; a2 = 0;}
else{a2 -= b; all -= 4 * b;}
if(all > a1) a1 = 0;
else a1 -= all;
ans += (a2 + 8) / 9;
r = a2 % 9;
all = 36 - 4 * r;
if(r){
if(all > a1) a1 = 0;
else a1 -= all;
}
ans += (a1 + 35) / 36;
printf("%d\n", ans);
}
return 0;
}
模仿网上代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
//freopen("in.txt", "r", stdin);
int a1, a2, a3, a4, a5, a6;
int b, x, ans;
int r[] = {0, 5, 3, 1};
while(scanf("%d%d%d%d%d%d", &a1, &a2, &a3, &a4, &a5, &a6) == 6)
{
if(0 == a1 + a2 + a3 + a4 + a5 + a6) break;
ans = a6 + a5 + a4 + (a3 + 3) / 4; //4*4,5*5,6*6都可以占一个箱子
b = 5 * a4 + r[a3%4]; //计算目前为止所开的箱子能够装下2*2的物品的最大数量
if(a2 > b) ans += (a2 - b + 8) / 9; //2*2的物品大于最大数量,应为剩下的开新的箱子
x = 36 * ans - 36 * a6 - 25 * a5 - 16 * a4 - 9 * a3 - 4 * a2; //计算目前为止所开的箱子能够装下1*1的物品的最大数量
if(a1 > x) ans += (a1 - x + 35) / 36; //1*1的物品大于最大数量,应为剩下的开新的箱子;
printf("%d\n", ans);
}
return 0;
}