Description
A factory produces products packed in square packets of the same height h and of the sizes 1*1, 2*2, 3*3, 4*4, 5*5, 6*6. These products are always delivered to customers in the square parcels of the same height h as the products have and of the size 6*6. Because of the expenses it is the interest of the factory as well as of the customer to minimize the number of parcels necessary to deliver the ordered products from the factory to the customer. A good program solving the problem of finding the minimal number of parcels necessary to deliver the given products according to an order would save a lot of money. You are asked to make such a program.
Input
The input file consists of several lines specifying orders. Each line specifies one order. Orders are described by six integers separated by one space representing successively the number of packets of individual size from the smallest size 1*1 to the biggest size 6*6. The end of the input file is indicated by the line containing six zeros.
Output
The output file contains one line for each line in the input file. This line contains the minimal number of parcels into which the order from the corresponding line of the input file can be packed. There is no line in the output file corresponding to the last ``null'' line of the input file.
Sample Input
0 0 4 0 0 1 7 5 1 0 0 0 0 0 0 0 0 0
Sample Output
2 1
解题思路:
很经典的题目,并不算简单,对于6*6,5*5,4*4的货物单独放一个箱子,对于3*3的箱子4个可以放满一个箱子,剩余空间应该优先放2*2的货物
对于5*5货物箱子剩下11个1*1空间,对于4*4还剩下5个2*2空间
对于箱子有1个3*3剩余空间5个2*2+7个1*1,对于有2个3*3剩余空间3个2*2+6个,对与3个3*3剩余空间1个2*2+5个1*1,
求出可以存放2*2的剩余空间,如果不能将2*2全部放入空隙需要另加箱子,然后求出所有箱子的空隙再存放1*1
代码:
#include<iostream>
#include<string>
#include<map>
#include<cstdio>
using namespace std;
int go[4]={0,5,3,1};
int main()
{
//freopen("aa.txt","r",stdin);
int a[7];
int num,b1,b2;
while(scanf("%d %d %d %d %d %d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])!=EOF)
{
if(a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0&&a[5]==0&&a[6]==0) break;
num=0;
num+=a[6]+a[5]+a[4]+(a[3]+3)/4;
b2=a[4]*5+go[a[3]%4];
if(a[2]>b2)
num+=(a[2]-b2+8)/9;
b1=num*36-a[6]*36-a[5]*25-a[4]*16-a[3]*9-a[2]*4;
if(a[1]>b1)
num+=(a[1]-b1+35)/36;
cout<<num<<endl;
}
return 0;
}
另解:
#include<iostream>
#include<string>
#include<map>
#include<cstdio>
using namespace std;
// 放置3*3的在6*6中的组合情况,优先放置更多的2*2
// 当放置1个3*3时,还可以放置7个1*1和5个2*2
// 当放置2个3*3时,还可以放置6个1*1和3个2*2
// 当放置3个3*3时,还可以放置5个1*1和1个2*2
int go[4][2]= {{0,0},{7,5},{6,3},{5,1}};
int main()
{
freopen("aa.txt","r",stdin);
int a[7];
int num,b2;
while(scanf("%d %d %d %d %d %d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])!=EOF)
{
if(a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0&&a[5]==0&&a[6]==0) break;
num=0;
num+=a[6]+a[5]+a[4]+(a[3]+3)/4;// 3*3,4*4,5*5,6*6一起用了几个
a[1]-=a[5]*11;//6*6的可以放置一个5*5和11个1*1,所以直接优先把1*1和5*5放在一个盒子里
b2=a[4]*4+go[a[3]%4][1];//已用的盒子中的空隙中共还可以放置多少个2*2
if(a[2]<=b2){ // 当已用盒子中的空隙可以放置完2*2盒子时
a[1]-=go[a[3]%4][0]; // 在空隙中与2*2组合的可以放置的1*1个数
a[2]-=b2;
a[1]+=a[2]*4; // 如果2*2是负数,那说明负数的绝对值是空隙,可以用来放置1*1
if(a[1]>0) // 如果1*1还有,那么要增加盒子
num+=(a[1]+35)/36;
}
else{ // 不能放置完2*2
a[1]-=go[a[3]%4][0]; //之前和2*2组合一起填满盒子的1*1
a[2]-=b2;
num+=(a[2]+8)/9; // 再增加盒子直到能放完2*2
a[1]-=(9-a[2]%9)*4; // 增加的盒子中可能不能占满2*2,还有空位可以放置1*1
if(a[1]>0)
num+=(a[1]+35)/36;
}
cout<<num<<endl;
}
return 0;
}