原题:http://poj.org/problem?id=1017
题意
已知:有6*6 的大箱子和 1*1,2*2,3*3,4*4,5*5,6*6 的木块
问:给定各种木块的数目,求最少需要多少个大箱子来装?
例如:
输入:0 0 4 0 0 1 -〉 输出 2
输入:7 5 1 0 0 0 -〉 输出 1
解题思想: 先放大的,后放小的
6*6的木块每个占用一个箱子;
5*5的木块每个占用一个新箱子,余下11个1*1的空格;
4*4的木块每个占用一个新箱子,余下5个2*2的空格;
3*3的木块每4个占用新一个箱子,不足4个也占一个新箱子,分情况余下不同数目的空格;
2*2的木块先填空格,空格不足开新箱子,每9个2*2的木块占一个新箱子;
1*1的木块先填空格,空格不足开新箱子,每36个占一个新箱子。
参考思路后,我的代码:
#include<stdio.h>
void main()
{
int N,a1,a2,a3,a4,a5,a6,x,y; //x为剩余1*1的空位,y为剩余2*2的空位
while(1)
{
scanf("%d%d%d%d%d%d",&a1,&a2,&a3,&a4,&a5,&a6);
if( a1 == 0 && a2 == 0 && a3 == 0 && a4 == 0 && a5 == 0 && a6 == 0 ) break;
N= a4+a5+a6+(a3+3)/4; //这里做a3/4向上取整,不能用N= a4+a5+a6+a3/4+1,
//否则结果比期望值大1
int u[4]={0,5,3,1}; //3*3的放的个数为4的倍数,4倍+1,4倍+2,4倍+3时,2*2可以放的
//个数
y=u[a3%4]+5*a4;
if(a2>y) N=N+(a2-y+8)/9; //这里做向上取整,不能用N=N+1+(a2-y)/9,否则结果比期望
//的结果大1
x=36*N-36*a6-25*a5-16*a4-9*a3-4*a2;
if(a1>x) N=N+1+(a1-x)/36;//N=N+(a1-x+35)/36;
printf("%d/n",N);
}
}
参考代码:
#include <iostream.h>
int Contain1[4] = { 0, 7, 6, 5 };
int Contain2[4] = { 0, 5, 3, 1 };
int nTotal;
void main() {
int b1,b2,b3,b4,b5,b6;
for(;;) {
cin>>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)/ 4;
if( b3 % 4) nTotal ++;
int c1; //当前能放 1*1 木块的空格数目
c1 = b5 * 11; //每个放5*5的箱子,还能放11个 1 * 1 的木块
c1 += Contain1[b3 % 4] ; //加上3*3箱子里能放的数目
int c2; //当前能放 2*2 木块的空格数目(先不考虑将1*1的木块放在 2*2的空格里)
c2 = b4 * 5; //每个放4*4的箱子,还能放5个 2 * 2 的木块
c2 += Contain2[b3 % 4]; //加上3*3箱子里能放的数目
if ( b2 <= c2 ) c1 += (c2 - b2) * 4 ;
else {
nTotal += ( b2 - c2) / 9; //每个空箱子可以放9个2 * 2
int r2 = (b2 - c2) % 9;
if( r2 )
{nTotal ++;
c1 += 36 - r2 * 4;
}
}
if( b1 > c1 )
{
nTotal += ( b1 - c1 ) / 36;
if(( b1 - c1) % 36 )
nTotal ++;
}
cout << nTotal << endl;
}//end for
}