您的位置:首页 > 其它

noi1805:碎纸机--搜索

2016-01-14 18:41 351 查看
http://noi.openjudge.cn/ch0205/1805/

题目分析:

搜索,从当前节点出发,扩展出两种状态,就是和下一个数组合与否, 超过了就剪枝,记录状态.,并判重.

先用了类似排列的做法,写了一上午,9个点过了6个,写的有的麻烦,懒得再改了.

然后参考了别人的代码,结果自己处理边界的出错,导致最后一个数是0的时候出错,然后花了不少时间才找出来.

#include<stdio.h>

#include<cstring>

#include<iostream>

using namespace std;

int step[8],ansstep[8],id;//step,存储分割的数组,ansstep,存储答案

int maxn,cs,re,nac,lac;//re,基数,nac等待分割的数,lac待分割数的长度 ,cs重复记录标志

char ac[8];

int num[8];//待分割的数组分成的单个数

void dfs(int sum,int cf ,int p,int depth ){//sum 记录和,cf当前数,p当前的位置,depth,组合到第几个数

if(sum+cf>re||cf>re||p>lac+1) return;

if(p==lac){//到了最后一个点,就计算.

step[depth]=cf;

int sums=sum+cf ;

if (sums<=re &&sums>=maxn){

if(sums>maxn){

memcpy(ansstep,step,sizeof(step));

maxn=sums;

cs=0;

id=depth;

}

else if(sums==maxn)cs++;

}

return;

}

step[depth]=cf;

dfs(sum+cf,num[p+1],p+1,depth+1);

if(p<=lac)dfs(sum,cf*10+num[p+1],p+1,depth);

}

int main( ){

int i;

while(1){

scanf("%d%s",&re,ac);

if(re==0 && ac[0]=='0') break;

lac=strlen(ac),nac=0;

memset(num,0,sizeof(num));

num[0]=0;

for(int i=0;i<lac;i++){

num[i+1]=ac[i]-'0';

nac=nac*10+num[i+1];

}

if(re==nac) {printf("%d %d\n",re,nac);continue;}

maxn=0;

cs=0;

id=0;

dfs(0,num[1],1,1);

if(maxn==0) printf("error\n");

else if(cs>0) printf("rejected\n");

else{

printf("%d ",maxn);

for(int i=1;i<id;i++){

printf("%d ",ansstep[i]);

}

printf("%d\n",ansstep[id]);

}

}

return 0;

}

出错的dfs

void dfs(int sum,int cf ,int p,int depth ){

if(sum+cf>re||cf>re||p>lac+1) return;
if(p==lac+1){	// 这里出错,多向下计算了一次,一般情况下没错,最后一个数字是0时候会重复计算.
if (sum<=re &&sum>=maxn){
if(sum>maxn){
memcpy(ansstep,step,sizeof(step));
maxn=sum;
cs=0;
id=depth;
}
else if(sum==maxn)cs++;
}
return;
}
step[depth]=cf;
dfs(sum+cf,num[p+1],p+1,depth+1);
dfs(sum,cf*10+num[p+1],p+1,depth);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: