测试输入包含若干测试用例,每个测试用例占一行,格式为"A B K",相邻两数字有一个空格间隔。当A和B同时为0时输入结束,相应的结果不要输出。
对每个测试用例输出1行,即A+B的值或者是-1。
1 2 1 11 21 1 108 8 2 36 64 3 0 0 1
3 -1 -1 100
能解释下下面的答案吗
#include <stdio.h> int main(){ int a,b,k,t; while(scanf("%d%d%d",&a,&b,&k)&&a+b>0){ t=1; t<<=k; printf("%d\n",(a-b)%t?a+b:-1); } }
#include <stdio.h> int main(){ int a,b,k,t; while(scanf("%d%d%d",&a,&b,&k)&&a+b>0){ t=1; t<<=k;//得到一个k位数能表示的最大数+1(也就是2^k) printf("%d\n",(a-b)%t?a+b:-1);//a-b:两数相减,得到一个结果,对结果对t取模(求余),如果余数为0,说明a、b的低位k位二进制数是相等的。 } }
代码可以换个方式来描述,可能更好理解:
#include <stdio.h> int main(){ int a,b,k,t; while(scanf("%d%d%d",&a,&b,&k)&&a+b>0){ t=1; t<<=k;//求2^k printf("%d\n",(a % t -b % t)?a+b:-1);//分别求a、b对t的余数,余数相等,低二进制k位相等 } }
题目有点模糊:
k位是字节位还是整数位?从你的描述好像是输入的整数位,但你提供的代码是字节位。
代码解释:
k位是整数位了。这也就是我不理解他的代码的原因哦
@yk_peng: 如果k位值的是整数,那么代码:
t<<=k
要修改为
t=10^k(也就是你的pow函数功能)。
@yk_peng:
另外:
既然k位不相等(k不大于8),那么,题目要求输入不大于10000的数字~~~其实意思就有点相悖了,所以,从出题人的本意是指二进制位 k 位,所以也就有了这段代码,只是出题人也没把意思描述清楚。
@519740105: 你应该是和我一样想的。可是他的代码也是Accepted的,会不会是我没理解到他的意思
@yk_peng: 出于这种目的
我又花积分下了其他人的代码
#include<stdio.h> int mod[8]={10,100,1000,10000,100000,1000000,10000000,100000000}; int main() { int a,b,k; while(scanf("%d%d%d",&a,&b,&k)!=EOF&&(a!=0||b!=0)) { if(a%mod[k-1]==b%mod[k-1]) printf("-1\n"); else printf("%d\n",a+b); } }
这个代码也是按10进制的K位处理的,Accepted
@yk_peng: 你的疑点:
(a-b)%t作为判断,为什么这样写吧?
在C里,表示TRUE和FALSE,是非零为TRUE和零为FALSE,也就是说,判断一个整数是否为TRUE是看这个整数为0。
代码:
printf("%d\n",(a-b)%t?a+b:-1);
修改为:
printf("%d\n",((a-b)%t) ==0?a+b:-1);
至于理解,其实,我们的理解都没错,是题目没描述清楚。当然,从题目前提看,我们也可以去“绞尽脑汁”的这样理解,只是题目也太欠国骂了。
@519740105: 没有了,C的语法我都吃烂了。。。
@yk_peng: 还纠结?给出的示例代码正确是在于k位是基于二进制的,而我们的理解都基于十进制了。题目描述有不明确的地方。
t<<=k;这步你单步跟踪就可以知道t变成多少了。
printf("%d\n",(a-b)%t?a+b:-1);
如果后面K位相同的话, (a-b)%t应该=0,也就是TRUE,显示结果a+b,否则显示-1
我就是不理解这句嘛:后面K位相同的话, (a-b)%t应该=0
用的位运算,看不懂。这样我知道 (a-b)%pow(10, k)==0
@yk_peng: 几个情况补充一下
1、我不清楚你写的答案对不对。
2、我知道那是位运算,但感觉位运算是2进制的,而不是10进制的,太久没有看C了,不清楚。你那样用POW函数肯定是没有错的。
3、对我来说,大概知道原理就够了,不追求细节正确(这个调试阶段可以搞定)。
@爱编程的大叔: 我就是不知道,他用这个位运算的原理了。
这是我的代码,用的10进制的方法
#include <stdio.h> int sq(int k) {int x; for(x=1; k--; x=x*10); return x;} int main(int argc, char *argv[]) { int A, B, K; while(scanf("%d%d%d", &A, &B, &K)!=EOF&&(A!=0 || B!=0)) printf("%d\n" , (A-B)%sq(K)?A+B:-1 ); return 0; }
那个最开始的代码也是Accepted的
我不是说你看不看得懂我写的,我写出来肯定是为了让人看懂的,我说的是你不看原理只看答案,就这样吧
原理就是如果两个数a和b的最后k位相同,那么a-b肯定能被10的(k)次方整除。
如:522-22=500能被10^2整除。
至于你代码里面的用的1来左移,我想是因为对于10^k总是能被2^k整除吧。