目录
问题描述
思路
问题描述中各长方形高度是与箱子高度相同的,因此只需要考虑长和宽,即二维平面的问题。
首先说一下总体思路:先放大的,后放小的。为什么要先放大的呢?因为题目要求求出最少的箱子数,若是箱子先放小的,那么到后面的箱子大的就放不进去,而要放入新的箱子里。若先放大的,那后面可以用小的方块填充。
下面是放方块的分析:
1. 4*4,5*5,6*6的块 单独占一个箱子
2. 3*3的块,每4块占一个箱子,余下的再占一个箱子
3. 如果箱子里放1个 3*3木块,那么还能 放5个2*2木块,以 及7个1*1木块
4. 如果箱子里放2个 3*3木块,那么还能 放3个2*2木块,以 及6个1*1木块
5. 如果箱子里放3个 3*3木块,那么还能 放1个2*2木块,以 及5个1*1木块
分析一:
- 6*6的木块每个占用1个新箱子;
- 5*5的木块每个占用1个新箱子,余下11个1*1的空格;
- 4*4的木块每个占用1个新箱子,余下5个2*2的空格;
- 3*3的木块每4个占用1个新箱子,不足4个也占1个新箱子, 分情况余下不同数目的空格;
- 2*2的木块先填空格,空格不足开新箱子,每9个2*2的木块 占1个新箱子;
- 1*1的木块先填空格,空格不足开新箱子,每36个占1个新 箱子
分析二:
设nTotal - 箱子数,b1~b6 - 1*1~6*6块个数
1) 先放好所有 6*6, 5*5, 4*4和3*3 的木块 由于每个4*4, 5*5, 6*6的木块需要单独占1个箱子; 每4个3*3的木块占1个箱子,余下的最多最少占1个箱子(这也是为什么b3要加3的原因)。
所以,它们需要的箱子总数为: nTotal = b6 + b5 + b4 + (b3+3)/4
2) 先把2*2的木块放到放有4*4木块的箱子里,在b4个箱子中可 以放b4*5个2*2的木块; 再把2*2的塞到放有3*3木块的箱子里:
设一个数组: int Contain2[4] = {0, 5, 3, 1}; Contain2[i] 表示当3*3木块的数目b3除以4的余数分别是 0,1,2,3时,会产生多少个能放2*2木块的空格。
放完2*2的木块后,再算一下有多少1*1的空格,能否把1*1 的木块都填进去,如果不能,也容易算出还要加多少个箱子。
3) 计算放好6*6, 5*5, 4*4, 3*3后留下多少空格能放2*2 c2 = 5 * b4 + Contain2[b3 % 4];
4) 在放好2*2的木块后,算留下多少空格能放1*1 c1 = 36 * nTotal - 36 * b6 - 25 * b5 - 16 * b4 - 9 * b3 - 4 * b2;
代码
#include <stdio.h>
int main( )
{
int b6,b5,b4,b3,b2,b1; //不同大小的木块个数
int nTotal = 0; //最少需要的箱子数目
int c1; //当前能放 1*1 木块的空格数目
int c2; //当前能放 2*2 木块的空格数目
int Contain2[4] = {0, 5, 3, 1};
while(1)
{
scanf("%d%d%d%d%d%d",&b1,&b2,&b3,&b4,&b5,&b6);
if (b1==0 && b2==0 && b3==0 && b4==0 && b5==0 && b6==0)
break;
nTotal = b6 + b5 + b4 + (b3 + 3)/4;
c2 = 5 * b4 + Contain2[b3%4];
if (b2 > c2) nTotal += (b2 - c2 + 8 ) / 9;//9个2*2填满一个箱子
c1 = 36 * nTotal - 36 * b6 - 25 * b5 - 16 * b4 - 9 * b3 - 4 * b2;
if (b1 > c1) nTotal += ( b1 - c1 + 35 ) / 36;//36个1*1填满一个箱子
printf("%d\n", nTotal);
}
return 0;