34 152 21 0
27 31 32 126 136 139 141 No solution.
假设A中去掉的数在第k+1位,可以把A分成三部分,低位,k,和高位。
A == a + b * 10^k + c * 10^(k+1)
B == a + c * 10^k
N == A + B == 2 * a + b * 10^k + c * 10^k * 11
其中b是一位数,b * 10^k不会进位,用10^k除N取整就可以得到b + 11c,再用11除,商和余数就分别是c和b了。但是这里有个问题a是一个小于10^k的数没错,但是2a有可能产生进位,这样就污染了刚才求出来的b + 11c。但是没有关系,因为进位最多为1,也就是b可能实际上是b+1,b本来最大是9,那现在即使是10,也不会影响到除11求得的c。因此c的值是可信的。然后根据2a进位和不进位两种情况,分别考虑b要不要-1,再求a,验算,就可以了。迭代k从最低位到最高位做一遍,就可以找出所有可能的A。
至于判断进位不进位 不需要直接判断 先不减b 求出a 此时的a是不进位的 然后b-- 再求a 此时的a就是进位的 判断这两个a时候合法即可
#include<stdio.h> int s[100]; int cnt=1; int cmp(const void *a,const void *b) { return *(int *)a-*(int *)b; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int N,i,a,b,c; while(scanf("%d",&N)!=EOF&&N!=0) { cnt=1; for(i=1;i<=N;i*=10) { c=(N/i)/11; b=(N/i)%11; if((b!=0||c!=0)&&b<10) { a=(N-(b*i+11*c*i))/2; if((a*2+b*i+11*c*i)==N) s[cnt++]=a+b*i+c*i*10; } b--; if((b!=0||c!=0)&&b>=0) { a=(N-(b*i+11*c*i))/2; if((a*2+b*i+11*c*i)==N) s[cnt++]=a+b*i+c*i*10; } } cnt--; if(cnt==0) {printf("No solution.\n");continue;} qsort(s+1,cnt,sizeof(s[1]),cmp); printf("%d",s[1]); for(i=2;i<=cnt;i++) if(s[i]!=s[i-1]) printf(" %d",s[i]); printf("\n"); } return 0; }
1.
if((b!=0||c!=0)&&b<10)
if((b!=0||c!=0)&&b>=0)这两个判断保持 0<=b<10
并且如果b==0 c==0 那么等于去删前导0没有意义
2.
a=(N-(b*i+11*c*i))/2; if((a*2+b*i+11*c*i)==N)这两个难道有意义吗?当然有意义 2a可能会为奇数 显然是不符合题意的 所以再验算排除这种情况 当然用odd()也行
3.判重要注意