最近计划好好刷一下poj上的题,打印了一下要刷的题集。决定先从深搜开始。第一道题是sticks,之前写过是参考网上的。今天又写了一边,权当回顾。
题目:给定n个等长木棒,将其随机断开得到m个短木棒(m>n)。现给定m个短木棒的长度,求原始木棒的最短长度len。
poj1011题目链接
这是一道dfs题目,比较经典。
主要思路 就是首先将所有的木棒按照长度做一个递减排序。令len的范围是 [ 短木棒的最长长度, 短木棒的长度和 ]。给定一个len值,进行dfs遍历。临界条件 是已组成的木棒数目 = 原始木棒的个数n。
注意
对于dfs题目,考虑使用全局变量和结构体进行数据的存储,比较方便。
对于循环输出,记得记得清空全局变量。
github默认讲tab解析为8个空格。所以为了美观,尽量将所用编辑器的tab设置为4个空格,或者禁用tab字符 (eg dev c++)。
个人代码如下。文末附原作者代码,注释比较详细。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <iostream> #include <algorithm> using namespace std ;struct Stick { int len; bool vis; }; Stick sticks[67 ]; int sum=0 ,n=0 ,total=0 ,k=0 ;bool cmp (Stick a,Stick b) { return a.len>b.len; } bool dfs (int num,int len,int pos) { if (num==total) return true ; for (int i=pos+1 ;i<n;i++) { if (sticks[i].vis) continue ; if (len+sticks[i].len==k) { sticks[i].vis=true ; if (dfs(num+1 ,0 ,-1 )) return true ; sticks[i].vis=false ; return false ; }else if (len+sticks[i].len<k) { sticks[i].vis=true ; if (dfs(num,len+sticks[i].len,i)) return true ; sticks[i].vis=false ; if (len==0 ) return false ; while (i+1 <n && sticks[i].len==sticks[i+1 ].len) i++; } } return false ; } int main () { while (cin >>n && n) { sum=0 ; for (int i=0 ;i<n;i++) { cin >>sticks[i].len; sticks[i].vis=false ; sum+=sticks[i].len; } sort(sticks,sticks+n,cmp); for (k=sticks[0 ].len;k<=sum;k++) { if (sum%k!=0 ) continue ; total=sum/k; if (dfs(1 ,0 ,-1 )) { cout <<k<<endl ; break ; } } } return 0 ; }
因原作者代码注释比较详细,此处就不详细介绍了,直接放代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include <iostream> #include <algorithm> using namespace std ;int total,l;int num,sum;typedef struct { int length; bool mark; }Sticks; Sticks sticks[70 ]; bool cmp (Sticks a,Sticks b) { return a.length>b.length; } int dfs (int s,int len,int pos) { if (s==total)return 1 ; for (int i=pos+1 ;i<num;i++) { if (sticks[i].mark)continue ; if (len+sticks[i].length == l) { sticks[i].mark = true ; if (dfs(s+1 ,0 ,-1 ))return true ; sticks[i].mark = false ; return false ; }else if (sticks[i].length+len<l){ sticks[i].mark = true ; if (dfs(s,len+sticks[i].length,i)) return true ; sticks[i].mark = false ; if (len==0 )return false ; while (sticks[i].length==sticks[i+1 ].length)i++; } } return false ; } int main () { while (cin >>num&&num!=0 ) { sum = 0 ; for (int i = 0 ; i < num; i++) { cin >>sticks[i].length; sum += sticks[i].length; sticks[i].mark = false ; } sort(sticks,sticks+num,cmp); for (l = sticks[0 ].length; l <= sum; l++) { if (sum%l!=0 )continue ; total = sum / l; if (dfs(1 ,0 ,-1 )) { cout <<l<<endl ; break ; } } } return 0 ; }