Packets
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
思路:
参考:点击打开链接
6*6 的产品每个会占用一个完整的箱子,并且没有空余空间;
5*5 的产品每个占用一个新的箱子,并且留下 11 个可以盛放 1*1的产品的空余空间;
4*4 的产品每个占用一个新的箱子,并且留下 5 个可以盛放 2*2 的产品的空余空间;
3*3的产品最复杂:3*3 的产品另开新的箱子,新开的箱子数目等于 3*3 的产品的数目除以4 向上取整;
需要讨论为 3*3 的产品新开箱子时,剩余的空间可以盛放多少 2*2 和1*1 的产品(这里如果有空间可以盛放 2*2 的产品,我们就将它计入 2*2 的空余空间,等到2*2 的产品全部装完,如果还有 2*2 的空间剩余,再将它们转换成 1*1 的剩余空间)
1. 3*3 的产品的数目正好是 4 的倍数,所以没有空余空间;
2. 3*3 的产品数目是 4 的倍数加 1,这时还剩 5 个 2*2 的空位和 7 个 1*1 的空位;
3. 3*3 的产品数目是 4 的倍数加 2,这时还剩 3 个 2*2 的空位和 6 个 1*1 的空位;
4. 3*3 的产品数目是 4 的倍数加 3,这时还剩 1 个 2*2 的空位和 5 个 1*1 的空位;
剩余的 2*2的空位和 2*2 产品的数目,如果产品数目多,就将 2*2 的空位全部填满,再为 2*2 的产品打开新箱子,同时计算新箱子中 1*1 的空位,如果剩余空位多,就将 2*2 的产品全部填入 2*2的空位,再将剩余的 2*2 的空位转换成 1*1 的空位;
最后处理 1*1 的产品,比较一下 1*1的空位与 1*1 的产品数目,如果空位多,将 1*1 的产品全部填入空位,否则,先将 1*1 的空位填满,然后再为 1*1 的产品打开新的箱子。
我自己的一些理解:
因为填充空隙时,均用2*2和1*1的箱子,所以从一开始从0开始计数,计算直至填满了3*3箱子后,需要的2*2和1*1的数目,记为count_1和count_2 。再与输入的数目比较,如果小于输入,自然就不需要再增加包裹。如果大于,则再计算。
ac代码:
#include<iostream>
using namespace std;
int Three_2[4]={0,5,3,1};//装有3*3的包裹可放2*2的个数,3*3 %4 依次剩0,1,2,3个
int Three_1[4]={0,7,6,5};//装有3*3的包裹可放1*1的个数,3*3 %4 依次剩0,1,2,3个
int main()
{
int box[7];//i=1,所以为7
int sumbox;
int count_1,count_2;
int ans;
while(1)
{
sumbox=0;
for(int i=1;i<=6;i++)
{
cin>>box[i];
sumbox+=box[i];
}
if(sumbox==0) break;
ans=box[6]+box[5]+box[4]+(box[3]+3)/4;//+3 防止box[3]<4
count_2=box[4]*5+Three_2[box[3]%4]; //2*2可放入4*4中和放入3*3中的个数
count_1=box[5]*11+Three_1[box[3]%4]; //1*1可放入5*5中和放入3*3中的个数
if(count_2<box[2])//如果不够放2*2。 开辟新的包裹
{
ans+=(box[2]-count_2+8)/9;//+8 防止剩下的box[2]<9,等式右边:新开包裹数
count_1+=4*(9* ((box[2]-count_2+8)/9)-(box[2]-count_2) );//开新包裹剩下的地方装1*1
}
else
count_1+=4*(count_2-box[2]);//刚好够放2*2或者有多余空间时,放1*1的箱子
if(count_1<box[1])//如果不够放1*1。 开辟新的包裹
ans+=(box[1]-count_1+35)/36;//+35 防止剩下的box[1]<36
cout<<ans<<endl;
}
return 0;
}