题意:
给一个目标正方形边长和n个小正方形的边长,问是否可以用这n个小正方形填满目标正方形。
分析:
dfs不一开始就定好放入顺序,而是用已放入的个数代表深搜维度。
代码:
#include <iostream>
using namespace std;
int box_size;
int n;
int size_num[16];
int col[64];
bool dfs(int cnt)
{
if(cnt==n)
return true;
int minx=INT_MAX,col_index;
for(int i=1;i<=box_size;++i)
if(minx>col[i]){
minx=col[i];
col_index=i;
}
for(int size=10;size>=1;--size){
if(!size_num[size]) continue;
if(box_size-col[col_index]>=size&&box_size-col_index+1>=size){
int t=0;
for(int c=col_index;c<=col_index+size-1;++c){
if(col[c]==col[col_index]){
++t;
continue;
}
break;
}
if(t==size){
size_num[size]--;
for(int c=col_index;c<=col_index+size-1;++c)
col[c]+=size;
if(dfs(cnt+1)) return true;
size_num[size]++;
for(int c=col_index;c<=col_index+size-1;++c)
col[c]-=size;
}
}
}
return false;
}
int main()
{
int cases;
scanf("%d",&cases);
while(cases--){
memset(size_num,0,sizeof(size_num));
memset(col,0,sizeof(col));
scanf("%d%d",&box_size,&n);
int cnt=0,area=0;
for(int i=1;i<=n;++i){
int size;
scanf("%d",&size);
++size_num[size];
area+=size*size;
if(size>box_size/2) ++cnt;
}
if(cnt>1||area!=box_size*box_size){
puts("HUTUTU!");
continue;
}
if(dfs(0)) puts("KHOOOOB!");
else puts("HUTUTU!");
}
return 0;
}