刷下存在感,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;
}