Description
Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square?
Input
The first line of input contains N, the number of test cases. Each test case begins with an integer 4 <= M <= 20, the number of sticks. M integers follow; each gives the length of a stick - an integer between 1 and 10,000.
Output
For each case, output a line containing "yes" if is is possible to form a square; otherwise output "no".
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
Source
看看是否可以用给定的木棍构成正方形,如果可以输出YES,不可以则输出NO
DFS+剪枝,1去掉sum%4!=0,2去掉有一根木棍大于avg的。
cjx做这题的时候一直超时,问题就在每次都遍历所有的木棍。如果将木棍排序后,那么每次只要从可以匹配的木棍的位置的下一个位置开始遍历就可以了。
#include <stdio.h> #include <algorithm> #include <iostream> using namespace std; int t,n; int a[21]; int visited[21]; int sum,avg,ans; void dfs(int begin,int sum,int time){ if(ans)return; if(time==3){ ans=1; return; }else{ for(int i=begin; i>=1;i--){ int now=sum+a[i]; if(!visited[i] && now<=avg){ visited[i]=1; if(now==avg){ dfs(n,0,time+1); }else{ dfs(i-1,now,time); } visited[i]=0; } } } } int main(int argc, char *argv[]) { scanf("%d",&t); while(t--){ scanf("%d",&n); sum=0; ans=0; for(int i=1; i<=n; i++){ scanf("%d",&a[i]); visited[i]=0; sum+=a[i]; } avg=sum/4; sort(a,a+n); if(avg*4!=sum || a[n]>avg){ puts("no"); continue; } dfs(n,0,0); if(!ans){ puts("no"); }else{ puts("yes"); } } return 0; }