题目大意:给你T组数据,每组数据有n个棍子,问你能不能用这些棍子拼成一个正方形(所有都要用上,而且不能截断棍子)。
Sample Input
3
4 1 1 1 1
5 10 20 30 40 50
8 1 7 2 6 4 4 3 5
Sample Output
yes
no
yes
芒果君:我以为这只是一道简单的dfs,没想到它虽然是简单的dfs,结果为了剪枝到不tle,耗了我整整两节自习课,人家明明和题解写的差不多来着,嘤嘤嘤,人家超想哭的>_< 至于怎么剪枝代码里已经很明显了,不容易想到的是,如果已经凑成3边了,一定能摆成正方形。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=25; 6 int M,sum,len[maxn],vis[maxn],T; 7 bool dfs(int cnt,int left,int begin) 8 { 9 if(cnt==4) 10 { 11 return true; 12 } 13 else 14 { 15 for(int i=begin;i<M;i++) 16 { 17 if(!vis[i]) 18 { 19 vis[i]=true; 20 if(left==len[i]) 21 { 22 if(dfs(cnt+1,sum/4,0)) 23 { 24 return true; 25 } 26 } 27 else if(len[i]<left) 28 { 29 if(dfs(cnt,left-len[i],i+1)) 30 { 31 return true; 32 } 33 } 34 vis[i]=false; 35 } 36 } 37 } 38 return false; 39 } 40 int main() 41 { 42 scanf("%d",&T); 43 while(T--) 44 { 45 int max_len=0; 46 sum=0; 47 scanf("%d",&M); 48 for(int i=0;i<M;i++) 49 { 50 scanf("%d",&len[i]); 51 max_len=max(max_len,len[i]); 52 sum+=len[i]; 53 } 54 if(sum%4!=0||max_len>sum/4) 55 { 56 printf("no\n"); 57 continue; 58 } 59 memset(vis,0,sizeof(vis)); 60 if(dfs(1,sum/4,0)) 61 { 62 printf("yes\n"); 63 } 64 else 65 { 66 printf("no\n"); 67 } 68 } 69 return 0; 70 }