题目链接:http://poj.org/problem?id=1117
题目翻译:给出一个数N,求X+Y = N的所有数对(X,Y),X,Y有如下要求,Y是X
这个数删除一位所得到的数,X不能含有前导0,但是Y可以含有前导0.
解题思路:
思路来源:http://poj.org/showmessage?message_id=350873
可以把X看成三部分。
AKB ,K是欲删除的那一位,所以Y 就是AB
X = (A*10 + K)*10^b + B, (b代表B是几位数)
Y = A*10^b + B
X + Y = (A*11 + K) * 10^b + 2*B = N
所以我们通过枚举B的值,来推导出A和K。
当N是奇数的时候,只可能是删除X的最后一位得到,(原因是如果B存在,则2*B%(10^b)取余
是N的后b位,因为2*B是偶数,所以N必然四偶数)。此时变成A*11 + K = N
由于K是一个数字,其值只能是0~9,故当N%11 != 10的时候是有解的。
1.N是奇数,N%11 != 10,有一个解。
2.N是偶数,还是需要考虑删除的是最后一位的情况,该情形和奇数的是一样的。
3.当枚举B的时候,又分为两种情况,2*B有进位,和2*B无进位,
即(2*B)%(10^b) = N%(10^b)
举个例子吧:
假设B是一位数,发现N的末尾是2,
则我们可以猜测的是,B = 1, 2*B = 2, 2*B无进位
然而B = 6,也是满足条件的,2*B = 12, 2*B%(10^b) = 2,即2*B向前进了1,其余数为2.
最后这样求解还可能存在重复的结果。
没有组合的时候记得输出答案数为0,做的时候自己忘输了,错了好几次。
AC代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
int power[] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
int res[10000000];
int ans[10000000];
///X+Y = N
int bitNumber(int x) {
int cnt = 0;
if(x == 0) return 1;
while(x) {
x = x/10;
cnt++;
}
return cnt;
}
int main() {
int N,A,B,K,temp,cnt,number;
while(~scanf("%d",&N)) {
cnt = 0;
if(N%11 != 10) { ///删除的是最后一位,11*A+k = N
K = N%11;
A = N/11;
res[cnt++] = A*10+K;
}
if(N%2 == 0) {
///枚举B的值,假设B的位数,B最大不超过N。
for(int i = 1; power[i] <= N; i++) {
/**由于2*B%power[i]取余等于N%power[i],
则2*B有可能小于power[i],2*B有可以能大于power[i],
也就是2*B会进一个1到i+1位,所以分成两种情况讨论*/
///1. 2*B无进位
B = (N%power[i])/2;
temp = (N-2*B)/power[i];
if(temp%11 != 10) {
K = temp%11;
A = temp/11;
res[cnt++] = (10*A+K)*power[i] + B;
}
///说明没有进位,则该情况结束
if(N/power[i]==1) break;
///考虑进位的情况
B = (power[i] + N%power[i])/2;
temp = (N-2*B)/power[i];
if(temp%11 != 10) {
K = temp%11;
A = temp/11;
res[cnt++] = (10*A+K)*power[i] + B;
}
}
}
if(cnt) {
sort(res,res+cnt);
ans[0] = res[0];
number = 1;
for(int i = 1; i < cnt; i++) {
if(res[i] == res[i-1])
continue;
else {
ans[number++] = res[i];
}
}
printf("%d\n",number);
for(int i = 0; i < number; i++) {
int numx = bitNumber(ans[i]);
int numy = bitNumber(N-ans[i]);
printf("%d + ",ans[i]);
for(int j = 1; j <= numx-1-numy; j++) {
printf("0");
}
printf("%d = %d\n",N-ans[i],N);
}
} else {
printf("%d\n",0); ///原来这里忘记了,WA了好几次
}
}
return 0;
}