poj.1416

这道题目的大体意思很简单就是三种可能的结果,另外操作就是沿着给出的一个数,求各种组合相加起来的结果,其结果不能超过原数,题目中有许多要注意的地方,题设已经给出了可能的三种输出,一种是正常输出即最大组合数,及相加所产生的结果,另一个就是直接输出原数,这就要求n与m必须相同,另外,就是error,这个时候,要求后一个数的所有组合情况都大于前一个数,转换过来就是后一个输入的数的每一个位数上的数相加所得数大于前一个数(因为这样组合相加的数是最小的),可以利用这两种请况分别构造两种条件语句进行判断,那么剩下的就是rejected和只有一个最大的组合数的情况,这时候就要用到dfs进行判断了,我的dfs函数的构造是建立在m第一位不为零的基础上的,而这也是题目所要求的,而且我的dfs函数是针对后一个数m至少为二设计的,所以调用dfs函数前面要判断len长度是否为1,另外,这道题目还有一个点,就是1203中,

1     2     0     3

1     2    03

是两种不同的情况。

当然这样的请况其实在我的dfs函数中就涵盖了,所以不需要做什么特殊的处理。

本题的另一个难点就是如何记录中途的各个数据,利用两个数组,一个record记录每一个中途的各个数据,另一个result记录最终的结果数据,他们的长度都不超过6,另外再加一个trag变量,用来判断是否最大数唯一,这样这道题就很清晰了,下面是我dfs的代码:(感觉bfs也可以)






#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define Max 7
char p[Max];//record
int trag;//1 -1
int n;
int maxn;
int len;
int point;
int record[Max];
int result[Max];
/*int Power(int x){
	if(x==0)
		return 1;
	else return 10*Power(x-1);
}*/
void DFS(int deep,int index,int piv)
{
	int i,j,k;
	//int temp=deep;
	int pivot=index;
	if(index==len-1){
		if(deep>maxn && deep<=n){
			trag=1;
			maxn=deep;
			for(i=0;i<piv;i++)
				result[i]=record[i];
			point=piv;
			return ;
		}
		else if(deep==maxn){ //&& deep>0){
			trag=-1;
			return ;
		}
		return ;
	}
	if(deep==0){
		for(i=0;i<=len-1;i++){
			index=pivot+i;
			int f=0;
			for(j=index,k=1;j>=0;j--,k*=10)
				f+=(p[j]-'0')*k;
			record[piv]=f;
			DFS(deep+f,index,piv+1);
		}
		//deep=temp;
	}
	else{
	for(i=1;i<=len-1;i++){
       if(pivot+i<len){
		index=pivot+i;
		 int f=0;
		for(j=index,k=1;j>=pivot+1;j--,k*=10)
			f+=(p[j]-'0')*k;
		record[piv]=f;
		//deep+=f;
		DFS(deep+f,index,piv+1);
	}
	//deep=temp;
	}
	}
}


int main()
{
	while(true)
	{
		scanf("%d",&n);
		getchar();
		scanf("%s",p);
		if(n==0 && p[0]=='0')
			break;
		int i,j,sum1=0,sum2=0;
		len=strlen(p);
		for(i=len-1,j=1;p[i];i--,j*=10){
			sum2+=p[i]-'0';
			sum1+=(p[i]-'0')*j;
		}
        if(sum1==n){
  printf("%d %d \n",n,n);
		continue;
		}
		else if(sum2>n){
			printf("error \n");
			continue;
		}
		else
		{
			if(len==1){
				printf("%d %d \n",p[0]-'0',p[0]-'0');
				continue;
			}
			maxn=0;
			DFS(0,0,0);
			if(trag==1)
			{
			   printf("%d ",maxn);
			   for(i=0;i<point;i++)
				   printf("%d ",result[i]);
			   printf("\n");
				continue;
			}
			else
				printf("rejected \n");
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值