poj 1416 Shredding Company(DFS)

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值