标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 16683 | Accepted: 5442 |
Description
Input
Output
Sample Input
2
4 8 1 1 1 1 1 3 1 1
5 6 3 3 2 1 1 1
Sample Output
KHOOOOB!
HUTUTU!
Source
大致意思是,有一块儿边长为s的正方形大蛋糕,问是否能不浪费地分割成n个边长不同的小蛋糕。可行则输出KHOOOOB!否则输出HUTUTU!
逆向思维,尝试用n个边长不同的小蛋糕拼成一个边长为s的正方形大蛋糕
搜索解决。为了便于处理状态,严格从左往右,从下往上地加入小蛋糕,填满下面的行才能填上面的行。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 int T,n,m; 7 int a[11];//边长为[i]的蛋糕的数量 8 int ck[50];//第[i]列已填的高度 9 bool dfs(int y){ 10 if(y==m)return 1; 11 int i,j; 12 // 13 int mi=200,pos=0; 14 for(j=1;j<=n;j++) 15 if(ck[j]<mi){ 16 mi=ck[j]; 17 pos=j; 18 } 19 // 20 for(i=10;i;i--){ 21 if(!a[i])continue;//没有该尺寸蛋糕,跳过 22 if(pos+i-1>n)continue;//该尺寸宽度比剩余宽度大,跳过 23 for(j=0;j<i;j++){ 24 if(ck[pos+j]<=ck[pos] && ck[pos+j]+i<=n)continue; 25 else break; 26 } 27 if(j<i)continue;//高度不足,跳过 28 for(j=0;j<i;j++)ck[pos+j]+=i; 29 a[i]--; 30 if(dfs(y+1))return 1; 31 a[i]++; 32 for(j=0;j<i;j++)ck[pos+j]-=i; 33 } 34 return 0; 35 } 36 int main(){ 37 scanf("%d",&T); 38 int i,j; 39 while(T--){ 40 memset(ck,0,sizeof ck); 41 memset(a,0,sizeof a); 42 scanf("%d%d",&n,&m); 43 int x; 44 int ssum=0; 45 int cnt=0; 46 for(i=1;i<=m;i++){ 47 scanf("%d",&x); 48 a[x]++; 49 ssum+=x*x; 50 if(x>n/2)cnt++;//尺寸大于n/2的蛋糕若有多块,肯定不可行 51 } 52 if(ssum!=n*n || cnt>1){ 53 printf("HUTUTU!\n"); 54 continue; 55 } 56 if(!dfs(0)){ 57 printf("HUTUTU!\n"); 58 } 59 else printf("KHOOOOB!\n"); 60 61 } 62 return 0; 63 }
标签:
原文地址:http://www.cnblogs.com/SilverNebula/p/5793839.html