这题可能是用贪心思想来写的,具体是不是我也不知道,自己对贪心也不是太清楚。之前好像写过,当时似乎没有写出来,不过,这次一下就有了思路。本来是想先装小的包裹,可是试了一下不行,有问题;于是改为先装大的包裹,如果有多余,再装小的,每次都这样,直到所有的包裹被装完为止。试了试,感觉没有什么问题。
代码写的可能有的乱,不过思路还是清楚的。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
int num[7];
bool visited[7][7];
bool judge(int size,int x,int y)//判断是否符合标准
{
int a=size+x-1,b=size+y-1;
if(a>6||b>6)//如果超过了6*6的范围显然不行
return false;
for(int i=x;i<=a;i++)
{
for(int j=y;j<=b;j++)//如果在所要求的区域中已经装过了,显然也不行
if(visited[i][j])
return false;
}
return true;
}
void set_true(int x,int y,int size)
{
int a=size+x-1,b=size+y-1;
for(int i=x;i<=a;i++)
for(int j=y;j<=b;j++)//用来标志已经装过了的区域
visited[i][j]=true;
}
bool isempty()
{
for(int i=1;i<=6;i++)//判断是否还有包裹没装
if(num[i]>0)
return true;
return false;
}
int main()
{
while(true)
{
bool isok=false;
for(int i=1;i<=6;i++)
{
scanf("%d",&num[i]);
if(num[i]!=0)
isok=true;
}
if(!isok)
break;
int ans=0;
while(isempty())
{
memset(visited,false,sizeof(visited));
for(int i=1;i<=6;i++)
{
for(int j=1;j<=6;j++)
{
if(visited[i][j])
continue;
for(int k=6;k>=1;k--)//从大到小开始装
{
if(num[k]==0)
continue;
if(judge(k,i,j))
{
set_true(i,j,k);
num[k]--;
break;
}
}
}
}
ans++;
}
printf("%d\n",ans);
}
return 0;
}