Question:http://poj.org/problem?id=1020
问题点:DFS。
1 Memory: 260K Time: 47MS 2 Language: C++ Result: Accepted 3 4 #include <iostream> 5 using namespace std; 6 7 int mat[40];//按列记录小块Cake填充状态 8 int side[16];//小块Cake边长 9 bool visit[16];//小块Cake是否已使用 10 int width,cnt;//大块Cake边长 小块Cake数量 11 bool flag;//是否能被填充标志 12 int cmp(const void* a,const void* b) 13 { 14 return *(int*)b - *(int*)a;//降序排列 15 } 16 //状态更新: pn为1时,从x列开始填充第idx块Cake,并判断是否能填充进去 17 // pn为-1时,从x列开始清除第idx块Cake 18 bool update(int idx,int x,int pn) 19 { 20 int i,temp = mat[x]; 21 if(pn == 1) 22 { 23 //填充第idx块Cake后,长宽不能超过边界 24 if(side[idx] + x > width || mat[x] + side[idx] > width) return false; 25 //判断x列到x+side[idx]-1列 是否同高度 26 for(i=1;i<side[idx];i++) 27 { 28 if(temp != mat[x+i]) return false; 29 } 30 visit[idx] = true; 31 } 32 else 33 { 34 visit[idx] = false; 35 } 36 for(i=0;i<side[idx];i++) 37 { 38 mat[x+i] += side[idx]*pn; 39 } 40 return true; 41 } 42 //获取当前最小高度处的最小列,填充顺序为"从低到高,从左到右" 43 int getLowX() 44 { 45 int i,temp=100; 46 for(i=0;i<width;i++) 47 { 48 temp =(temp<mat[i]?temp:mat[i]); 49 } 50 for(i=0;i<width && temp!= mat[i];i++); 51 return i; 52 } 53 //idx为已填充数 ,x为小块Cake编号 54 void dfs(int idx,int x) 55 { 56 if(idx == cnt) {//当全部填充完毕时,返回true 57 flag = true; 58 return; 59 } 60 for(int i=0,w=0;i<cnt;i++) 61 { 62 if(visit[i]) continue;//已填充的不再填充 63 if(w == side[i]) continue; else w = side[i];//同边长的不重复填充 64 if(update(i,x,1))//在x列填充第i块Cake 65 { 66 dfs(idx+1,getLowX()); 67 if(flag) return; 68 update(i,x,-1);//在x列清除第i块Cake 69 } 70 } 71 } 72 int main() 73 { 74 int eg; 75 cin>>eg; 76 while(eg--) 77 { 78 int i,j,k; 79 memset(mat,0,sizeof(mat)); 80 memset(side,0,sizeof(side)); 81 memset(visit,0,sizeof(visit)); 82 flag = false; 83 cin>>width; 84 cin>>cnt; 85 for(i=0;i<cnt;i++) 86 { 87 cin>>side[i]; 88 } 89 qsort(side,cnt,sizeof(int),cmp);//排序用于去重 90 dfs(0,0); 91 if(flag) cout<<"KHOOOOB!"<<endl; 92 else cout<<"HUTUTU!"<<endl; 93 } 94 //system("pause"); 95 return 0; 96 }