poj1017 Packets 题解报告

题目传送门

【题目大意】

有6种规格的物品,分别是$6*6,5*5,4*4,3*3,2*2,1*1$,高度均为$H$,先有一种高为$H$,规格为$6*6$的包裹可以装物品,求最少需要多少个包裹可以装下所有物品。

【思路分析】

分类讨论一下:

1.$6*6$的物品每个都要一个包裹

2.$5*5,4*4$的物品每个包裹也只能装一个,但要记录余下的空间可以存放几个$1*1$和$2*2$的物品

3.$3*3$的物品每个包裹可以装4个,对于每个箱子里装了不同个$3*3$的物品的情况,可以存放不同个数$2*2$的物品,也要记录

4.先把前面所有可以放$2*2$的物品的位置装完,然后如果有剩余,再另开箱子

5.先把前面所有的空余位置装完,然后如果有剩余,另开箱子存放$1*1$的物品

很多细节部分要注意,详见代码。

【代码实现】

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include
 6 #define g() getchar()
 7 #define rg register
 8 #define go(i,a,b) for(rg int i=a;i<=b;i++)
 9 #define back(i,a,b) for(rg int i=a;i>=b;i--)
10 #define db double
11 #define ll long long
12 #define il inline
13 #define pf printf
14 using namespace std;
15 int fr(){
16     int w=0,q=1;
17     char ch=g();
18     while(ch<'0'||ch>'9'){
19         if(ch=='-') q=-1;
20         ch=g();
21     }
22     while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g();
23     return w*q;
24 }
25 int num[7],a1=0,a2=0,ans=0,tag[4]={0,5,3,1};
26 //tag记录的是放了i个3*3的物品之后,还能放多少个2*2的
27 int main(){
28     //freopen("","r",stdin);
29     //freopen("","w",stdout);
30     rg int end=0;
31     while(1){
32         a1=0;a2=0;ans=0;end=0;
33         go(i,1,6){
34             num[i]=fr();
35             end+=num[i];
36         }
37         if(!end) break;
38         back(i,6,1){
39             if(!num[i]) continue;
40             if(i==6) {ans+=num[i];continue;}
41             if(i==5) {ans+=num[i];a1+=11*num[i];continue;}//a1记录可以放多少个1*1的物品
42             if(i==4) {ans+=num[i];a2+=5*num[i];continue;}//a2记录可以放多少个2*2的物品
43             if(i==3){
44                 rg int add=ceil(1.0*num[i]/4);ans+=add;
45                 if(add*4>num[i]){
46                     rg int a2_add=tag[num[i]%4];
47                     a2+=a2_add;
48                     a1+=(add*4-num[i])*9-a2_add*4;
49                 }
50             }
51             if(i==2){
52                 if(num[i]continue;}
53                 num[i]-=a2;a2=0;
54                 rg int add=ceil(1.0*num[i]/9);ans+=add;
55                 if(add*9>num[i]) a1+=(add*9-num[i])*4;
56             }
57             if(i==1){
58                 a1+=a2*4;
59                 if(num[i]continue;}
60                 num[i]-=a1;
61                 rg int add=ceil(1.0*num[i]/36);ans+=add;
62             }
63         }
64         pf("%d\n",ans);
65     }
66     return 0;
67 }
代码戳这里

你可能感兴趣的:(poj1017 Packets 题解报告)