Poj 1011 -- Sticks (search), poj1011 -- sticks
Question Link
Description
George took sticks of the same length and cut them randomly until all parts became at most 50 units long. now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. please help him and design a program which computes the smallest possible original length of those sticks. all lengths expressed in units are integers greater than zero.
Input
The input contains blocks of 2 lines. the first line contains the number of sticks parts after cutting, there are at most 64 sticks. the second line contains the lengths of those parts separated by the space. the last line of the file contains zero.
Output
The output shoshould contains the smallest possible length of original sticks, one per line.
Sample Input
95 2 1 5 2 1 5 2 141 2 3 40
Sample Output
65
Q: I have n wooden sticks. I want to splice these n wooden sticks into a wooden sticks with the same length as x. Should I make the new wooden sticks as short as possible and output the minimum value?
Idea: search, the length of the new wooden stick must be greater than or equal to the maximum value of the original wooden stick maxlen, less than or equal to the total length of these wooden sticks sum, so from small to large (maxlen ~ Sum) to traverse these values, if sum % I! = 0, you cannot directly skip a valid wooden stick;
If sum % I = 0, the search may be successful. Search process: a deep search records the number of wooden sticks that have been combined. How long is the current competition from the wooden sticks, the used wooden sticks are marked with v [I.
The Code is as follows:
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;int start,sum;int v[70];int check(int num,int rest,int pos){ if(num==sum/start) return 1; rest-=pos; v[pos]--; if(rest==0) { int i; for(i=50; i>=1; i--) if(v[i]) break; int flag=check(num+1,start,i); v[pos]++; return flag; } for(int i=rest; i>=1; i--) { if(!v[i]) continue; int flag=check(num,rest,i); if(flag) return 1; } v[pos]++; return 0;}int main(){ int n; while(scanf("%d",&n)&&n) { int maxn=-1; sum=0; memset(v,0,sizeof(v)); for(int i=1; i<=n; i++) { int x; scanf("%d",&x); sum+=x; v[x]++; maxn=max(maxn,x); } for(start=maxn; start<=sum; start++) { if(sum%start!=0) continue; if(check(0,start,maxn)) { printf("%d\n",start); break; } } } return 0;}/**921 16 33 36 19 1 35 6 47ans=1074346 16 47 31 22 48 10 47 25 48 33 31 35 33 14 21 8 22 20 37 20 48 8 18 3 44 28 16 9 50 44 18 46 28 43 49 18 19 31 46 3 43 43ans=141*//**204 2 1 6 6 5 6 9 1 0 6 9 0 4 8 3 2 1 1 6206 8 9 4 5 10 6 5 8 5 5 7 9 6 3 10 3 1 9 9*/