Problem 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

University of Waterloo Local Contest 2002.09.21

 

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int m,edge;//木棍的个数,木棍的边长
 5 int stick[25];//木棍的长度
 6 bool vis[25];//是否用过木棍
 7 bool flag;
 8 void dfs(int n,int len,int i)//n是第几条边,len是这条边已有长度,i从第几条边开始查找(防止超时)
 9 {
10     if(n==5)//终止条件
11     {
12         flag=true;
13         return;
14     }
15     if(len==edge)
16     {
17         dfs(n+1,0,1);
18         if(flag==true)
19             return ;
20     }
21     for(int j=i;j<=m;j++)
22     {
23         if(!vis[j])
24         {
25             if(stick[j]+len<=edge)
26             {
27                 vis[j]=true;
28                 dfs(n,len+stick[j],j+1);
29                 if(flag==true)
30                     return ;
31                 vis[j]=false;
32             }
33         }
34     }
35     
36 }
37 int main()
38 {
39     int T;
40     cin>>T;
41     while(T--)
42     {
43         cin>>m;
44         edge=0;
45         for(int i=1;i<=m;i++)
46         {
47             cin>>stick[i];
48             edge+=stick[i];
49         }
50         if(edge%4!=0)//第一个剪枝:是否能组成正方形
51         {
52             printf("no\n");
53             continue;
54         }
55         edge/=4;
56         int i;
57         for(i=1;i<=m;i++)//第二个剪枝:木棍小于等于边长
58         {
59             if(stick[i]>edge)
60                 break;
61         }
62         if(i!=m+1)
63         {
64             printf("no\n");
65             continue;
66         }
67         memset(vis,false,sizeof(vis));
68         flag=false;
69         dfs(1,0,1);
70         if(flag)
71             printf("yes\n");
72         else
73             printf("no\n");
74     }
75     return 0;
76 }