POJ 1017 Packets
Packets
Packets
Packets
大意:给你一些包,他们的大小是 1*1,2*2,3*3,4*4,5*5,6*6, 高都是h,让你放到6*6高度为h的箱內,希望用的箱子最少
思路:由于盒子和箱子的高均为h,因此只需考虑底面积的空间。
6*6的盒子,每个盒子独占一个箱子。
5*5的盒子,每个盒子放入一个箱子,该箱子的剩余空间允许放入的最大尺寸为1*1,且最多放11个
4*4的盒子,每个盒子放入一个箱子,该箱子的剩余空间允许放入的最大尺寸为2*2。
3*3的盒子,每4个刚好独占一个箱子,不足4个3*3的,剩下空间由2*2和1*2填充。
2*2的盒子和1*1的盒子主要用于填充其他箱子的剩余空间,填充后的多余部分才开辟新箱子装填。
1 # include <map> 2 # include <queue> 3 # include <stack> 4 # include <math.h> 5 # include <stdio.h> 6 # include <string.h> 7 # include <iostream> 8 # include <algorithm> 9 #define LL long long 10 #define max(a,b) (a>b?a:b) 11 using namespace std; 12 13 void run() 14 { 15 int a, b, c, d, e, f, cnt = 0; 16 while(~scanf("%d%d%d%d%d%d", &a, &b, &c, &d, &e, &f) && (a+b+c+d+e+f)) 17 { 18 int Ans = 0; 19 Ans += f; 20 Ans += e; 21 a = max(0, a-e*11); 22 Ans += d; 23 if(b >= d*5) 24 b -= d*5; 25 else 26 { 27 a = max(0, a-4*(d*5-b)); 28 b = 0; 29 } 30 Ans += (c+3)/4; 31 c %= 4; 32 if(c) 33 { 34 if(b >= 7-2*c) 35 { 36 b -= 7-2*c; 37 a = max(0, a-(8-c)); 38 } 39 else 40 { 41 a = max(0, a-(36-9*c-4*b)); 42 b = 0; 43 } 44 } 45 Ans += (b+8)/9; 46 b %= 9; 47 if(b) 48 a = max(0, a-(36-4*b)); 49 Ans += (a+35)/36; 50 printf("%d\n", Ans); 51 } 52 } 53 54 int main(void) 55 { 56 run(); 57 58 return 0; 59 }
这是用模拟的方法做的,但是做的时候总觉得应该不是用模拟来做,于是搜了一下,果然有简单的方法
1 #include <iostream> 2 using namespace std; 3 int u[4] = {0, 5, 3, 1}; //装有3*3 的箱子可放2*2的包数 当放1个3*3可以放5个2*2 2个可放3个2*2 4 int v[4] = {0, 7, 6, 5}; 5 int main(){ 6 int a, b, c, d, e, f, x, y, t, z; 7 while(cin>>a>>b>>c>>d>>e>>f && a|b|c|d|e|f){ 8 z = d + e + f + (c+3)/4; //3*3的包1~4个装一个箱子里 9 x = 11*e + v[c%4]; //x是1*1的包可以放到装了5*5包的箱子里11个 10 y = d*5 + u[c%4]; //y是2*2的包可以放到装了4*4包的箱子里5个 11 if(y < b){ // 如果可装2*2的个数小于2*2的总个数新开箱子 每1~9开一个新箱子 12 t = (b-y+8)/9; 13 z += t; 14 x += 4 * (9*t - (b-y)); //开新箱子剩下的地方装1*1的包 15 } 16 else 17 x += 4 * (y - b); //可以装1*1包的地方增加 18 if(x < a) 19 z += (a - x + 35) / 36; //如果可装1*1的个数小于1*1的总个数新开箱子 每1~36开一个新箱子 20 cout<<z<<endl; 21 } 22 return 0; 23 }