本来想优化的,可是实在是想不出来怎么优化呀,92ms,囧死了。 思路是看了别人的,就是DFS,中间没有剪枝吧,不对,有的,在放小正方形时,can函数判断一下,行不行,不行,剪の。 #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXN 11 #define MAXSIZE 41 int s[MAXN], d[MAXSIZE], big_size, small_num, all_small; inline bool can(int size, int row) { if(row-1+size>big_size) return false; for(int i=row+1; i<row+size; ++i) if(d[i]>d[row]) return false; return true; } bool DFS(int n, int remaind) { if(0==n) if(0==remaind) return true; else return false; int row=1; for(int i=2; i<=big_size; ++i) if(d[i]<d[row]) row=i; for(int i=1; i<=10; ++i) if(s[i]&&big_size-d[row]>=i) { if(can(i,row)) { for(int j=row; j<row+i; ++j) d[j]+=i; --s[i]; if(DFS(n-1,remaind-i*i)) return 1; for(int j=row; j<row+i; ++j) d[j]-=i; ++s[i]; } else continue; } return false; } void init() { memset(s,0,sizeof(s)); memset(d,0,sizeof(d)); all_small=0; } int main() { int case_num,tp; scanf("%d",&case_num); while(case_num--) { init(); scanf("%d%d",&big_size,&small_num); for(int i=0; i<small_num; ++i) { scanf("%d",&tp); ++s[tp]; all_small+=tp*tp; } if(big_size*big_size==all_small&&DFS(small_num,big_size*big_size)) printf("KHOOOOB!/n"); else printf("HUTUTU!/n"); } return 0; }