码迷,mamicode.com
首页 > 其他好文 > 详细

poj-1117

时间:2016-05-12 21:43:38      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

刷下存在感,poj的1117 http://poj.org/problem?id=1117

题目要求,

给定一个数N,

找出一个数A, 把去掉A的中的一个数字的数称为B, 使得 A + B = N. 找出所有这样的组合。


这是一道递归题, 

我们把A ==> upArray,

B ==> downArray.

那么对应每一位的加法,比如说第k位的相加,总有下面的情况,

1,  A中的第k位就是被删除的数字,那么他就可以取,0~9

2.  分二种情况, 如果之前已经有被删除的数字了,那么A只能取B的第k-1位。  如果之前还没有被删除的数字,那么A的第k位要么是第一种情况,要么与B的第k位相等


所以可以得到下面的代码

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

#define  MAX 100001

struct Key
{
	unsigned key;
	char data[11];
};

Key OutputValue[MAX];
int KeyNum = 0;

/*
@param
	len 最大的长度,
	nArray 结果数字
	k 当前的长度
	pos 之前有没有进位
	upArray 上面已经选的数字
	downArray 下面已经选的数字
*/
bool SearchPair(int len, int nArray[], int k, int pos, int upArray[], int downArray[], bool bNew)
{
	if(k == len){
		if(pos == 0 && bNew){
			
			int len1 = 0;
			int len2 = 0;
			for(len1 = len - 1; len1 >=0; len1 --){
				if(upArray[len1] != 0)
					break;
			}

			for(len2 = len - 1; len2 >=0; len2 --){
				if(downArray[len2] != 0)
					break;
			}
			if(len2 >= len1)
				return false;
			len = len1 + 1;

			Key temp;
			temp.key = 0;
			for(int i = 0; i < len; i++)
			{
				temp.key = temp.key * 10 + upArray[len - i - 1];
			//	printf("%d", upArray[len - i - 1]);
			}
		//	printf("\n");
			int i;
			for(i = 1; i < len; i++)
			{
				temp.data[i - 1] = downArray[len - i - 1] + '0';
	//			printf("%d", downArray[len - i - 1]);
			}
			temp.data[i - 1] = 0;
		//	printf("%d\n", i - 1);
			bool bWrite = true;
			for(int i = 0; i < KeyNum; i ++)
			{
				if(OutputValue[i].key == temp.key){
					bWrite = false;
				}
			}
			if(bWrite)
				OutputValue[KeyNum ++] = temp;
		//	printf("\n");
			return true;
		}
		return false;
	}
	int digit = nArray[k];		// 注意这个digit为0的情况
	int downDigit;// = downArray[k - 1];
	if(k == 0){
		downDigit = -1;
	}
	else{
		downDigit = downArray[k - 1];
	}

	int CanGet[3] = {0};
	CanGet[0] = downDigit;

	// 上面的数字, 三个选择,1,新的,2,等于下面的k,3,等于下面的k-1, 只有能一个是新的(被删掉的数字)
	// 分二种,前面已经有删掉的数字,只能取k-1,否则有二种情况

	// 已经有删除的数字,只能取前一个
	if(bNew)
	{
		int newPos = 0;
		upArray[k] = downDigit;
		downArray[k] = (digit - pos - downDigit);
		
		if(downArray[k] < 0){
			downArray[k] += 10;
			newPos = 1;
		}

		if(SearchPair(len, nArray, k + 1, newPos, upArray, downArray, bNew))
			return true;

	}
	else{
		// 这种情况才能一样,取一样的,
		if((digit == 0 && pos == 0) ||
			((digit - pos ) % 2 == 0))
		{
			int value = (digit - pos) /2 ;
			CanGet[1] = value;
			upArray[k] = downArray[k] = value;
			SearchPair(len, nArray, k + 1, 0, upArray, downArray, bNew);
			//	return true;


			value = (digit - pos + 10) / 2;
			CanGet[2] = value;
			upArray[k] = downArray[k] = value;
			SearchPair(len, nArray, k + 1, 1, upArray, downArray, bNew);
			//	return true;
		}

		// 这一种,这一个数字成删除数字
		for(int i = 0; i < 10; i ++)
		{
			//bool bGood = true;
			//for(int j = 0; j < 3; j ++)
			//{
			//	if(i== CanGet[j]){
			//		bGood = false;
			//		break;
			//	}
			//}
		//	if(bGood){

				int newPos = 0;
				upArray[k] = i;
				downArray[k] = (digit - pos - i);

				if(downArray[k] < 0){
					downArray[k] += 10;
					newPos = 1;
				}

				SearchPair(len, nArray, k + 1, newPos, upArray, downArray, true);
				//	return true;

			}
	//	}


	}
	return false;
}
int cmp(const void *a, const void *b){
	return (*(Key*)a).key - (*(Key*)b).key;

}

int main()
{
	unsigned int N;
	
	while(scanf("%u", &N) != EOF)
	{
		unsigned int NN = N;
		int nArray[10] = {0};
		int len = 0;
		do 
		{
			nArray[len++] = N % 10;
			N = N / 10;
		} while (N != 0);
		int upArray[10];
		int downArray[10];
		KeyNum = 0;
		SearchPair(len, nArray, 0, 0, upArray, downArray, false);
		
		qsort((void*)OutputValue, KeyNum, sizeof(OutputValue[0]), cmp);

		printf("%d\n", KeyNum);
		for(int i = 0; i < KeyNum; i ++){
			
			printf("%u + %s = %d\n", OutputValue[i].key, OutputValue[i].data, NN);
		}
	}
	return 0;
}


poj-1117

标签:

原文地址:http://blog.csdn.net/scut_lyq00/article/details/51351966

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!