参考自:这位博主~
描述
1.每次切割之前,先要给定碎纸机一个目标数,而且在每张被送入碎纸机的纸片上也需要包含一个数。
2.碎纸机切出的每个纸片上都包括一个数。
3.要求切出的每个纸片上的数的和要不大于目标数而且与目标数最接近。
举一个例子,如下图,假设目标数是50,输入纸片上的数是12346。碎纸机会把纸片切成4块,分别包含1,2,34和6。这样这些数的和是43 (= 1 + 2 + 34 + 6),这是所有的分割方式中,不超过50,而又最接近50的分割方式。又比如,分割成1,23,4和6是不正确的,因为这样的总和是34 (= 1 + 23 + 4 + 6),比刚才得到的结果43小。分割成12,34和6也是不正确的,因为这时的总和是52 (= 12 + 34 + 6),超过了50。
还有三个特别的规则:
1.如果目标数和输入纸片上的数相同,那么纸片不进行切割。
2.如果不论怎样切割,分割得到的纸片上数的和都大于目标数,那么打印机显示错误信息。
3.如果有多种不同的切割方式可以得到相同的最优结果。那么打印机显示拒绝服务信息。比如,如果目标数是15,输入纸片上的数是111,那么有两种不同的方式可以得到最优解,分别是切割成1和11或者切割成11和1,在这种情况下,打印机会显示拒绝服务信息。
为了设计这样的一个碎纸机,你需要先写一个简单的程序模拟这个打印机的工作。给定两个数,第一个是目标数,第二个是输入纸片上的数,你需要给出碎纸机对纸片的分割方式。输入输入包括多组数据,每一组包括一行。每行上包括两个正整数,分别表示目标数和输入纸片上的数。已知输入保证:两个数都不会以0开头,而且两个数至多都只包含6个数字。
输入的最后一行包括两个0,这行表示输入的结束。
输出对每一组输入数据,输出相应的输出。有三种不同的输出结果:
sum part1 part2 ...
rejected
error
第一种结果表示:
1.每一个partj是切割得到的纸片上的一个数。partj的顺序和输入纸片上原始数中数字出现的次序一致。
2.sum是切割得到的纸片上的数的和,也就是说:sum = part1 + part2 +...
第一种结果中相邻的两个数之间用一个空格隔开。
如果不论怎样切割,分割得到的纸片上数的和都大于目标数,那么打印“error”。
如果有多种不同的切割方式可以得到相同的最优结果,那么打印“rejected”。
样例输入
50 12346 376 144139 927438 927438 18 3312 9 3142 25 1299 111 33333 103 862150 6 1104 0 0样例输出
43 1 2 34 6 283 144 139 927438 927438 18 3 3 12 error 21 1 2 9 9 rejected 103 86 2 15 0 rejected
解题思路:
经典的dfs。关键在于对数字的划分,以50 12346为例。采用搜索方式可为0 1 3 6 10 16 52 37 43 349 24 28 34 70 235 2347 12 15 19 25 61 46 52 358 123 1234 12346。当长度达到5时开始判断。
# include<stdio.h> # include<string> # include<string.h> # include<iostream> using namespace std; int a[10],len; int n,length,k=0; int b[10],tmp[10]; int flag=0; int ans; void dfs(int sum,int pos,int cnt)//当前的数字和,a数组下标,b数组下标 { // printf("%d ",sum); if(sum>n) return;//如果ans最终也一直为-1,error if(pos==len) { if(sum==ans) { flag=1; return;//reject } else if(sum>ans) { ans=sum; flag=0; for(int j=0;j<cnt;j++) { b[j]=tmp[j]; length=cnt; } } return; } int total=0; for(int k=pos;k<len;k++) { int t=a[k]; total*=10; total+=t; tmp[cnt]=total; dfs(sum+total,k+1,cnt+1);//这里下一次是k,而不是pos! } } int main() { int i,j; string s; while(cin>>n>>s) { if(n==0&&s=="0") break; int sum=0; len=s.size(); for(i=0;i<len;i++) { a[i]=s[i]-'0'; sum*=10; sum+=a[i]; } if(sum==n) { printf("%d %d\n",n,sum); continue; } ans=-1; dfs(0,0,0);//sum,pos,cnt if(ans==-1) { printf("error\n"); } else { if(flag==1) printf("rejected\n"); else { printf("%d",ans); for(j=0;j<length;j++) { printf(" %d",b[j]); } printf("\n"); } } } return 0; }