Problem Description
Gardon和小希玩了一个游戏,Gardon随便想了一个数A(首位不能为0),把它去掉一个数字以后得到另外一个数B,他把A和B的和N告诉了小希,让小希猜想他原来想的数字。不过为了公平起见,如果小希回答的数虽然不是A,但同样能达到那个条件(去掉其中的一个数字得到B,A和B之和是N),一样算小希胜利。而且小希如果能答出多个符合条件的数字,就可以得到额外的糖果。
所以现在小希希望你编写一个程序,来帮助她找到尽可能多的解。
例如,Gardon想的是A=31,B=3 告诉小希N=34,
小希除了回答31以外还可以回答27(27+7=34)所以小希可以因此而得到一个额外的糖果。
Input
输入包含多组数据,每组数据一行,包含一个数N(1<=N<=10^9),文件以0结尾。
Output
对于每个输入的N,输出所有符合要求的解(按照大小顺序排列)如果没有这样的解,输出"No solution."
Sample Input
34 152 21 0
Sample Output
27 31 32 126 136 139 141 No solution.
枚举拿去的那一位数的位置,将原来的数字拆成A+B+C的形式,B表示的是拿去的那一个数字,A和C分别表示被拿去的数的前面部分和后面部分
那么原来的数字a可以表示成A*10^k+B*10^k-1+C
拿去数字时候的那个数字就可以表示成A*10^k-1+C
相加等于N即得出答案,枚举B和K,判断是否可行即可,注意细节处理
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <set> #include <vector> using namespace std; int p10[10] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000}; int solve(int n) { int len = log10(n) + 1; set<int> note; //c不进位 for(int b = 0;b <= 9;b++) { for(int k = 1;k <= len;k++) { int n1 = n / p10[k - 1]; if((n1 - b) % 11 == 0 && n % p10[k - 1] % 2 == 0) { int c = n % p10[k - 1] / 2,a = (n1 - b) / 11; note.insert(a * p10[k] + b * p10[k - 1] + c); } } } //c进位 for(int b = 0;b <= 9;b++) { for(int k = 2;k <= len;k++) { int n1 = n / p10[k - 1] - 1; if(n1 != 0 && (n1 - b) % 11 == 0 && n % p10[k - 1] % 2 == 0) { int c = (n % p10[k - 1] + p10[k - 1]) / 2,a = (n1 - b) / 11; int num = p10[k - 1] * (11 * a + b) + 2 * c; note.insert(a * p10[k] + b * p10[k - 1] + c); } } } if(note.empty()) { printf("No solution."); } else { printf("%d",*note.begin()); note.erase(note.begin()); while(!note.empty()) { printf(" %d",*note.begin()); note.erase(note.begin()); } } printf(" "); } int main() { int n; while(scanf("%d",&n),n) { solve(n); } return 0; }