HDU ACM 1518 Square (DFS)
http://acm.hdu.edu.cn/showproblem.php?pid=1518
题意:给出若干条木棒,求用上所有木棒能不能组成一个正方形.
输入:第一行输入T,表示有T组数据
然后给出一个n, 表示有n跳木棒
接下来n个数表示木棒长度.
输出:能输出yes 不能输出no
因为知道木棒的总长度,所以能算出边长.
只要遍历每一条边就能,就能找到是否存在解.
可以用深搜实现,直接深搜不剪枝会超时.
剪枝的方法:对于同一条边,已经搜索过的不需要再搜索.
对于同一条边找到第一个位置时进入不需要从0开始重新搜索.而是从他上一层找到的位置开始搜索.
因为上一层搜索过的已经是被标记过,无用的.
这样能把原本O(N^2)的复杂度变成O(N)的复杂度.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 int side; 4 int n; 5 int flag; 6 int used[11000]; 7 int num[11000]; 8 void DFS(int now,int cnt,int k)// now--现在长度 cnt--几条 k--现在搜到哪个位置 9 { 10 11 if(now == side) 12 { 13 cnt++; 14 k = 0; 15 now = 0; 16 if(cnt == 4) 17 { 18 flag = 1; 19 return ; 20 } 21 } 22 int i; 23 for(i = k;i<n;i++) 24 { 25 if(!used[i]) 26 { 27 used[i] = 1; 28 if( now + num[i] <= side) 29 { 30 DFS(now + num[i],cnt,i+1);//注意不能是 now = now + num[i]; DFS(now,cnt,i+1); 31 if(flag) 32 { 33 return ; 34 } 35 } 36 used[i] = 0; 37 } 38 } 39 } 40 int main() 41 { 42 int T; 43 cin>>T; 44 while(T--) 45 { 46 cin>>n; 47 int i; 48 memset(used,0,sizeof(used)); 49 int sum = 0; 50 for(i=0;i<n;i++) 51 { 52 cin>>num[i]; 53 sum = sum + num[i]; 54 } 55 if(sum % 4 ) 56 { 57 cout<<"no"<<endl; 58 } 59 else 60 { 61 flag = 0; 62 side = sum / 4; 63 for(i=0;i<n;i++) 64 { 65 if(num[i] > side) 66 { 67 flag = 1; 68 break; 69 } 70 } 71 if(flag) 72 { 73 cout<<"no"<<endl; 74 } 75 else 76 { 77 flag = 0; 78 DFS(0,0,0); 79 if(flag) 80 { 81 cout<<"yes"<<endl; 82 } 83 else 84 { 85 cout<<"no"<<endl; 86 } 87 } 88 } 89 } 90 return 0; 91 }