题目链接:http://poj.org/problem?id=1416
用DFS暴搜,枚举出所有状态,直至搜索完毕,计算最小值。
我是用map来标记出现次数,开数组太浪费空间了。
具体代码如下(变量有点多= =!):
#include<iostream>
#include<cmath>
#include<map>
using namespace std;
const int maxn=10;
char tarNum[maxn],shredNum[maxn];
int target,shred,maxNum,lenTar,lenShred,len;
int a[maxn],p[maxn];
int parseInt(char *a,int len){//字符串转换成数字
int ans=0;
for(int i=0;i<len;i++){
ans=ans*10+a[i]-'0';
}
return ans;
}
int getValue(char *a,int len){//计算各个位数之和
int ans=0;
for(int i=0;i<len;i++){
ans+=a[i]-'0';
}
return ans;
}
map<int,int>M;
void dfs(int index,int num,int deep){
if(index>lenShred-1){
if(maxNum<=num){
maxNum=num;//更新满足条件的最大值
M[maxNum]++;//统计maxNum出现的次数
len=deep;//记录数组的长度
for(int i=0;i<deep;i++)//记录路径
p[i]=a[i];
}
return ;
}
int tmp=0;
for(int i=index;i<lenShred;i++){//枚举从index开始的所有可能的状态
tmp=tmp*10+(shredNum[i]-'0');
if(num+tmp<=target){//如果当前值小于目标值,继续搜索,否则退出
a[deep]=tmp;
dfs(i+1,num+tmp,deep+1);
}
else
break;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
while(~scanf("%s%s",tarNum,shredNum)){
if(!strcmp(tarNum,"0")&&!strcmp(shredNum,"0")) break;
memset(a,0,sizeof(a));
memset(p,0,sizeof(p));
lenTar=strlen(tarNum);
lenShred=strlen(shredNum);
target=parseInt(tarNum,lenTar);
if(parseInt(shredNum,lenShred)==target){//如果相等,不需要剪碎
printf("%d %d\n",target,target);
continue;
}
shred=getValue(shredNum,lenShred);
if(shred>target){//最小值大于目标值,不存在,直接输出error
printf("error\n");
continue;
}
maxNum=0,len=0,M.clear();//初始化
dfs(0,0,0);
if(M[maxNum]>1)//最大值出现不只一次,记得上一步要讲map清空
printf("rejected\n");
else{
printf("%d",maxNum);
for(int i=0;i<len;i++)
printf(" %d",p[i]);
putchar(10);
}
}
return 0;
}