整数对
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2572 Accepted Submission(s): 879
所以现在小希希望你编写一个程序,来帮助她找到尽可能多的解。
例如,Gardon想的是A=31,B=3 告诉小希N=34,
小希除了回答31以外还可以回答27(27+7=34)所以小希可以因此而得到一个额外的糖果。
假设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.判重要注意