乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。
现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。
给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。
输入格式: 输入文件共有二行。
第一行为一个单独的整数N表示砍过以后的小木棍的总数,其中N≤65
(管理员注:要把超过50的长度自觉过滤掉,坑了很多人了!)
第二行为N个用空个隔开的正整数,表示N根小木棍的长度。
输出格式: 输出文件仅一行,表示要求的原始木棍的最小可能长度
输入样例#1: 9 5 2 1 5 2 1 5 2 1 输出样例#1: 6
(恶心题目,始终过不了,复制了网上大神的代码)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> using namespace std; int n; int a[100]; int cnt=0; bool vis[100]; bool dfs(int num,int len,int s,int pos) { int ok=1; if(num==1){printf("%d",s);exit(0);} int p=-1; for(int i=pos;i>=1;i--) { if(!vis[i]&&a[i]!=p) { vis[i]=1; if(len+a[i]<s) { if(dfs(num,len+a[i],s,i-1)){printf("%d",s);exit(0);} if(len==0){vis[i]=0;return 0;} } if(len+a[i]==s) { if(dfs(num-1,0,s,cnt)){printf("%d",s);exit(0);} else{vis[i]=0;break;} } vis[i]=0; p=a[i]; } } return 0; } int main() { scanf("%d",&n); int l=0; int sum=0; for(int i=1;i<=n;i++) { int c;scanf("%d",&c); if(c<=50) { sum+=c; a[++cnt]=c; l=max(l,c); } } sort(a+1,a+1+cnt); for(int i=l;;i++) { if(sum%i==0) { memset(vis,0,sizeof(vis)); if(dfs(sum/i,0,i,cnt)) { printf("%d",i); return 0; } } } return 0; }