有一块边长为Big的正方形的大蛋糕,现在给出n块不同尺寸的正方形的小蛋糕的边长,问是否能把大蛋糕按恰好切割为这n块小蛋糕,要求每块小蛋糕必须为整块。
思路:把每块小蛋糕放进边为big的盒子里,dfs从大块到小块放,想到了这个思路,但还是不会敲代码,可能是敲得少,想不出怎么设置数组,怎么来判断错误的条件。参考acm之家的Java代码写出c的
#include<stdio.h>
#include <string.h>
int sum,t,big,n,length[11],d[41],ok=0;//d是横坐标
void dfs(int a)
{
int i,j,put,p=0;
bool f;
if(a==n)
{
ok=1;
return ;
}
//寻找未填的横坐标最小的点的纵坐标,
for(i=1,put=41;i<=big;i++)
{
if(d[i]<put)
{put=d[i];
p=i;}
}
for(i=10;i>=1;i--)
{
if(length[i]>0&&put+i-1<=big&&p+i-1<=big)//是否超出边界
{
for(j=p,f=1;j<=p+i-1;j++)<span style="font-family: Arial, Helvetica, sans-serif;">//判断每列是否放得下</span>
if(d[j]>put)
{
f=false;
break;
}
if(f)//递归回溯
{
for(j=p;j<=p+i-1;j++)
d[j]+=i;
length[i]--;
dfs(a+1);
length[i]++;
for(j=p;j<=p+i-1;j++)d[j]-=i;
}
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&big,&n);
sum=ok=0;
memset(length,0,sizeof(length));
int i,p;
for(int i=1;i<=40;i++)
d[i]=1;
for(i=1;i<=n;i++)
{
scanf("%d",&p);
sum+=p*p;
length[p]++;
}
if(sum!=big*big)
{
printf("HUTUTU!\n");
continue;
}
dfs(0);
if(ok)printf("KHOOOOB!\n");
else printf("HUTUTU!\n");
}
return 0;
}