标签:
刷下存在感,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; }
标签:
原文地址:http://blog.csdn.net/scut_lyq00/article/details/51351966