1.链接地址:
http://bailian.openjudge.cn/practice/2817/
http://poj.org/problem?id=1011
2.题目:
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
- 乔治拿来一组等长的木棒,将它们随机地裁断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘 记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。
- 输入
- 输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。
- 输出
- 为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。
- 样例输入
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0- 样例输出
6 5- 来源
- POJ 1011
3.思路:
递归 + 剪枝
4.代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 6 using namespace std; 7 8 int cmp(const void *a,const void *b) 9 { 10 int ia = *((int *)a); 11 int ib = *((int *)b); 12 13 return ib - ia; 14 } 15 16 int k; 17 int L; 18 19 bool f(int *sticks,int left_L,int left_n) 20 { 21 22 int i; 23 int flag = true; 24 25 //cout<< "f(" << "," << left_L << "," << left_n << ")" <<endl; 26 //for(i = 0; i < k; ++i) cout << sticks[i] << " "; 27 //cout << endl; 28 29 for(i = 0; i < k; ++i) 30 { 31 32 if(sticks[i] != 0) 33 { 34 flag = false; 35 int temp; 36 if(sticks[i] == left_L) 37 { 38 temp = sticks[i]; 39 sticks[i] = 0; 40 if(f(sticks,L,left_n - 1)) return true; 41 sticks[i] = temp; 42 } 43 else if(sticks[i] < left_L) 44 { 45 temp = sticks[i]; 46 sticks[i] = 0; 47 if(f(sticks,left_L - temp,left_n)) return true; 48 sticks[i] = temp; 49 } 50 else continue; 51 52 if(left_L == L || sticks[i] == left_L) break;//Less 1 53 } 54 } 55 56 if(flag && left_n == 0) return true; 57 else return false; 58 } 59 60 61 int main() 62 { 63 //freopen("C://input.txt","r",stdin); 64 65 int i; 66 67 while(cin>>k) 68 { 69 if(k == 0) break; 70 71 int *sticks = new int[k]; 72 memset(sticks,0,sizeof(k)); 73 74 for(i = 0; i < k; ++i) cin >> sticks[i]; 75 76 qsort(sticks,k,sizeof(int),cmp); 77 78 int sum = 0; 79 for(i = 0; i < k; ++i) sum += sticks[i]; 80 81 int n; 82 for(L = sticks[0]; L <= sum; ++L) 83 { 84 if(sum % L != 0) continue; 85 86 n = sum / L; 87 if(f(sticks,L,n)) 88 { 89 cout << L << endl; 90 break; 91 } 92 } 93 } 94 return 0; 95 }