题目描述:
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
代码如下:
1 /*要剪枝,当所有木棒总长度不能被4整除时以及木棒最大长度大于总长度除以4时, 2 * 不能组成正方形,直接输出no 3 * 深搜时从第一个开始往后搜索,只要满足当前边长+当前木棒长<正方形边长, 4 * 就标记该木棒,并继续搜索后面的木棒,当木棒长度=sum/4 时,count加1, 5 * 当count=3时表明能够成正方形,flag=1,返回,flag=0则不能组成正方形。*/ 6 #include<iostream> 7 #include<cstring> 8 9 int visit[20]; 10 bool flag; 11 int number[20]; 12 int n,len; 13 14 using namespace std; 15 16 void dfs(int cur,int pos,int count); 17 int main() 18 { 19 int m; 20 cin >> m; 21 while(m--) 22 { 23 int max = 0,sum = 0; 24 cin >> n; 25 memset(visit,0,sizeof(visit)); 26 for(int i = 0;i < n;i++) 27 { 28 cin >> number[i]; 29 sum += number[i]; 30 if(number[i] > max) 31 max = number[i]; 32 } 33 len = sum / 4; 34 if(sum % 4 != 0 || max > len)//不能总和不能被4整除或最大值大于平均值 35 { 36 cout << "no" << endl; 37 continue; 38 } 39 flag = 0; 40 dfs(0,0,0); 41 if(flag) 42 cout << "yes" << endl; 43 else 44 cout << "no" << endl; 45 } 46 } 47 48 void dfs(int cur,int pos,int count) 49 { 50 if(cur == len)//木棍相加的值等于平均值 51 { 52 count++; 53 cur = 0;//当一边成立时,要考虑另外一边注意将cur清0 54 pos = 0; 55 if(count == 3)//当有三边成立时 56 { 57 flag = 1; 58 return; 59 } 60 } 61 for(int i = pos;i < n;i++) 62 { 63 if(!visit[i])//还没有被访问过 64 { 65 if((cur + number[i]) <= len)//加上木棍后,长度小于或等于平均值 66 { 67 visit[i] = 1; 68 dfs(cur + number[i],i,count); 69 if(flag)//一旦有成立的,跳过剩下的判断 70 return; 71 visit[i] = 0;//回溯 72 } 73 } 74 } 75 }
代码分析:
这道题目要注意的地方就是剪枝。
参考地址:http://www.cnblogs.com/PegasusWang/archive/2013/04/08/3008942.html