问题描述:
一个工厂生产的产品形状都是长方体,高度都是h,主要有1*1,2*2,3*3,4*4,5*5,6*6等6种。这些产品在邮寄时被包装在一个6*6*h的长方体包裹中。由于邮费很贵,工厂希望减小每个订单的包裹数量以增加他们的利润。因此他们需要一个好的程序帮他们解决这个问题。你的任务就是设计这个程序。
输入:
输入包括多组测试数据,每一行代表一个订单。每个订单里的一行包括六个整数,用空格隔开,从小到大分别为这6种产品的数量。6个0表示文件结束。
输出要求:
针对每个订单输出一个整数,占一行,代表对应的订单所需的最小包裹数。没有多余的空行。
输入样例:
0 0 4 0 0 1
7 5 1 0 0 0
0 0 0 0 0 0
输出样例:
2
1
解题分析:
6*6:毫无疑问,6*6的产品每个都会占用一整个箱子,因此有多少个6*6的产品,必须有多少个箱子,而且没有任何空余的空间存放其他产品。
5*5:该产品也必须自己占用一个箱子,但是会有剩余,剩余的部分为6*6-5*5=11,这11个空间很显然只能存放1*1大小的产品,因此,5*5的可以和1*1放在一起,可以放11个1*1的产品。
4*4:该产品也需要自己占用一个箱子,剩余的空间既可以放5个2*2的产品,也可以放20个1*1的产品。
3*3:4个3*3的产品正好可以装满一个整箱子。如果3*3的产品数来对4求余的余数为0,直接除以4就是所需的箱子数,不再有剩余空间。
如果余数不为0,那么则是除以4取整后再加1,这时候就会出现剩余空间。
如果余数为1,1个箱子里只放1个3*3的产品,那么剩余的空间为27,最多可以放5个2*2的箱子和7个1*1的箱子。
如果余数为2,则剩余的空间为18,最多可以放3个2*2的箱子和6个1*1的箱子。
如果余数为3,则剩余空间为9,最多只能放1个2*2和5个1*1。
(注:这里考虑剩余空间,紧着比较大的箱子去放,也就是紧着2*2的箱子放,所以没有写空隙全部放1*1小箱子的情况)
2*2:可以和4*4或3*3产品放一起,如果空隙占满了箱子还没放完,则需要占用新箱子,9个2*2产品正好占满一个箱子,所需新箱子的数量应该对9求余,余数为0,则直接整除9即可,否则整除9后再加1。
1*1:与2*2类似,先把所有剩余的1*1空间占满,如果不够,则重新占用新箱子,一个箱子可以存放36个1*1,因此剩余的1*1产品数对36求余,余数为0,直接整除36,否则整除36加1。
最后把这6种情况各自所需的箱子数累加起来就是题目所要的结果。
代码(主要是从最大的箱子开始分析,小箱子就是插空用的,最后再考虑小箱子的剩余情况)(贪心算法)https://zhuanlan.zhihu.com/p/53334049
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int a,b,c,d,e,f;
while(1){
scanf("%d %d %d %d %d %d",&a,&b,&c,&d,&e,&f);
if(a==0&&b==0&c==0&d==0&e==0&f==0) break;
int i=f;//6*6的箱子单独占一个
int t;//用于存放放3*3箱子后还能装多少2*2箱子的变量
if(e>0){
i+=e;//5*5的箱子单独占一个
a-=(11*e);//5*5其余空隙放1*1箱子后剩下的1*1箱子数量
}
if(d>0){
i+=d;//4*4的箱子单独占一个
b-=(5*d);//4*4其余空隙全部放2*2箱子后剩下的2*2箱子数量
if(b<=0){//2*2箱子放完了还有空隙,就放1*1的
a-=(d*16)-b*4;//剩下空间都放1*1箱子之后1*1箱子的剩余数量
b=0;
}
else{//2*2箱子放完后没有空隙
b-=(d*5);
}
}
if(c>0){//放3*3箱子
i+=(c/4);//一个大箱子装4个3*3箱子
c%=4;
if(c){//3*3箱子放不满大箱子,余数有3,2,1三种情况
i++;
t=(4-c)*2-1;//放c个3*3的箱子后还能放下t个2*2的箱子
if(b>t){//2*2箱子放空隙没放下
b-=t;//剩余的2*2箱子
a-=(36-9*c-4*t);//剩余空隙放1*1
}
else{//2*2箱子全部能放空隙里
b=0;
a-=(36-9*c-4*b);//剩余空间放1*1
}
}
}
if(b>0){//放剩下的2*2箱子
i+=(b/9);//一个大箱子放9个2*2箱子
if(b%9){//一个箱子全放2*2之后还剩有2*2的箱子
i++;
a-=(36-((b%9)*4));//剩余空隙放1*1箱子
}
}
if(a>0){
i+=(a/36);//一个大箱子放36个1*1箱子
if(a%36) i++;
}
printf("%d\n",i);
}
return 0;
}