#include<iostream>
#include<fstream>
using namespace std;
int countBox;
int count1Dot1;
int count2Dot2;
int Cal(int array[])
{
int i,j,k;
for(i=6;i>=1;i--)
{
switch(i)
{
case 6:
{
countBox+=array[6];
break;
}
case 5:
{
countBox+=array[5];
count1Dot1+=array[5]*11;
break;
}
case 4:
{
countBox+=array[4];
count2Dot2+=array[4]*5;
break;
}
case 3:
{
j=array[3]%4;
k=array[3]/4+1;//向上取整
switch(j)
{
case 0:
{
countBox+=(array[3]/4);
break;
}
case 1:
{
countBox+=k;
count1Dot1+=7;
count2Dot2+=5;
break;
}
case 2:
{
countBox+=k;
count1Dot1+=6;
count2Dot2+=3;
break;
}
case 3:
{
countBox+=k;
count1Dot1+=5;
count2Dot2+=1;
break;
}
}
break;
}
case 2:
{
if(array[2]<=count2Dot2)
{ count2Dot2-=array[2];
count1Dot1+=(4*count2Dot2);//剩余的2*2记得转为1*1
count2Dot2=0;
}
else
{
int Much=array[2]-count2Dot2;//剩余多少2*2
int t=Much/9;//6*6可以有9个2*2个箱子向上取整
if(Much%9!=0)//向上取整
{ t++;
count1Dot1+=((9-Much%9)*4);
}
countBox+=t;
}
break;
}
case 1:
{
if(array[1]<=count1Dot1)
{ count1Dot1-=array[1];}
else
{
int Much=array[1]-count1Dot1;
int t=Much/36;
if(Much%36!=0)
t++;
countBox+=t;
count1Dot1+=(Much%36);
}
break;
}
}
}
return countBox;
}
int main()
{
int array1[7];
int num0=0;
while(true)
{
num0=0;
for(int i=1;i<=6;i++)
{ scanf("%d",&array1[i]);}
for(int i=1;i<=6;i++)
{
if(array1[i]==0)
num0++;
}
if(6==num0)
{ break;}
int k=Cal(array1);
printf("%d\n",k);
countBox=0;
count1Dot1=0;
count2Dot2=0;
}
}
AC过的代码,尚未优化,题目的思路,下面再讲,先上代码。
求解问题的思路:
贪心算法:先放大件,再放小件。
int countBox;//统计需要的箱子数
int count1Dot1;//统计空余的1*1数
int count2Dot2;//统计空闲的2*2数
具体说明如下:
6*6:需要占用一个箱子
5*5:占用一个箱子 余11个 1*1
4*4:占用一个箱子,余5个2*2
3*3:
若4*n+1:余5个2*2,7个1*1
若4*n+2余3个2*2,6个1*1
若4*n+3余1个2*2,5个1*1
用swich语句,从6*6处理到1*1;
注意实现:向上取整,直接可以用统一表达式:
int Need=(array[1]-count1Dot1+35)/36;//向上取整的办法;
未优化的向上取整,采用
int Much=array[1]-count1Dot1;
int t=Much/36;
if(Much%36!=0)
t++;
countBox+=t;
count1Dot1+=(Much%36);
显得过于累赘,容易出错。
统计1*1空闲位置的表达式采用:
count1Dot1=countBox*36-array[6]*36-array[5]*25-array[4]*16-array[3]*9-array[2]*4;//计算空闲1*1空间。
未优化的方法,计算该值过于繁琐。
程序容易出现错误的地方是:
countBox=0;
count1Dot1=0;
count2Dot2=0;
每组数据处理完之后,忘记进行初始化。
该POJ:非常容易出错,必须进行大量的数据测试过后,才可以保证争取,样例只有两个例子,命令过少。
我采用1000个数据进行测试,最终修改过很多次,才AC了。
经验:有时候,测试样例没问题,但就是Wrong Answer,那说明你的程序逻辑有问题,对某些测试数据不行。
解决方法:
网上寻找测试数据,进行测试,跟能够AC过的程序进行对比,可以观察两个程序运行过程中的中间变量等等。
http://poj.org/showmessage?message_id=111906附有本题的测试数据
#include<iostream>
//****************算法变量*********************
int countBox;//统计需要的箱子数
int count1Dot1;//统计空余的1*1数
int count2Dot2;//统计空闲的2*2数
//****************题目变量*********************
int input[7];//输入数组
int Cal(int array[])
{
int i,j,k;
for(i=6;i>=1;i--)
{
switch(i)
{
case 6:
countBox+=array[6];
break;
case 5:
countBox+=array[5];
break;
case 4:
countBox+=array[4];
count2Dot2+=array[4]*5;
break;
case 3:
j=array[3]%4;
k=(array[3]+3)/4;//向上取整
switch(j)
{
case 0:
countBox+=k;
break;
case 1:
countBox+=k;
count2Dot2+=5;
break;
case 2:
countBox+=k;
count2Dot2+=3;
break;
case 3:
countBox+=k;
count2Dot2+=1;
break;
}
break;
case 2:
if(array[2]<=count2Dot2)
count2Dot2-=array[2];
else
{
int Need=(array[2]-count2Dot2+8)/9;//
countBox+=Need;
}
break;
case 1:
{
count1Dot1=countBox*36-array[6]*36-array[5]*25-array[4]*16-array[3]*9-array[2]*4;//计算空闲1*1空间
if(array[1]<=count1Dot1)
{ count1Dot1-=array[1];}
else
{
int Need=(array[1]-count1Dot1+35)/36;//向上取整的办法
countBox+=Need;
}
break;
}
}
}
return countBox;
}
int main()
{
int num0=0;
while(true)
{
num0=0;
for(int i=1;i<=6;i++)
{ scanf("%d",&input[i]);}
for(int i=1;i<=6;i++)
{
if(input[i]==0)
num0++;
}
if(6==num0)
{ break;}
int k=Cal(input);
printf("%d\n",k);
countBox=0;
count1Dot1=0;
count2Dot2=0;
}
}