对应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; }