题目链接: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; }