第一种方法过不了测评系统,虽能输出正确结果,但忽略了这是木棍,结果的长度需要小木棍拼接。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int a[100],b[10]; 5 int main(){ 6 int n,sum,maxn=0,h=0,k=0; 7 while(cin>>n){ 8 if(n==0) 9 break; 10 sum=0; 11 for(int i=0;i<n;i++){ 12 cin>>a[i]; 13 if(a[i]>maxn) 14 maxn=a[i]; 15 sum+=a[i]; 16 } 17 for(int i=maxn;i<=sum;i++) 18 if(sum%i==0){ 19 b[h++]=i; 20 k=h; 21 break; 22 } 23 } 24 for(int i=0;i<k;i++) 25 cout<<b[i]<<endl; 26 return 0; 27 }
第二种方法用DFS搜索
思路:
1、搜索原始长度L初始值设为大最长小木棍1的值,进行深搜。
2、深搜目的主要为能使每根小木棍匹配到能和它组成长度L的小木棍,且每根小木棍都能找到“组织”,记录每个“组织”的总和为sum。
深搜方法:遍历每种小木棍组合的可能性,结合递归进行。
将所有可能性全部遍历不可能,因此要进行剪枝。
剪枝:
1、sum==L且记录所用小木棍数量t==n时,说明我们假设的L符合,输出L;当t!=n时,只能证明这个小木棍组合符合目前我们对L的判断,但之后的小木棍是否符合并不知道。为了记录后面小木棍组合长度所以要将sum更新为0。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 int a[100]; 6 int used[5]; 7 int n; 8 bool cmp(int a,int b){ 9 return a>b; 10 } 11 int DFS(int L,int sum,int t){ 12 if(sum==L&&t==n)return 1; 13 if(sum==L) sum=0; 14 for(int i=0;i<n;i++){ 15 if(i>0&&!used[i]||a[i]==a[i-1])continue;//长度为某值的小木棍被搜过且被淘汰,则与其长度相等的木棍均不再进行搜索。 16 if(used[i]&&sum+a[i]>L)continue;//某值小木棍加入“组合”后超过预期值,则淘汰。 17 used[i]=1;//以上情况遇到的小木棍全部标记为搜索过 18 if(DFS(i,sum+a[i],t++)) return 1; 19 else{ 20 used[i]=0; 21 if(!sum||sum==L)return 0; 22 } 23 } 24 } 25 int main(){ 26 memset(used,0,sizeof(used)); 27 int maxn,ans; 28 while(scanf_s("%d",&n)!=EOF){ 29 ans=0; 30 for(int i=0;i<n;i++){ 31 cin>>a[i]; 32 ans+=a[i]; 33 } 34 sort(a,a+n,cmp); 35 for(int i=a[0]+1;i<=ans;i++){ 36 if(DFS(i,0,0)){ 37 cout<<i<<endl; 38 break; 39 } 40 } 41 } 42 return 0; 43 }