首页 新闻 会员 周边 捐助

C题目,求答案解释,小白我看不懂

0
悬赏园豆:50 [已解决问题] 解决于 2014-09-25 14:11
题目描述:
读入两个小于10000的正整数A和B,计算A+B。需要注意的是:如果A和B的末尾K(不超过8)位数字相同,请直接输出-1。
输入:

测试输入包含若干测试用例,每个测试用例占一行,格式为"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);
    }
}

 

yk_peng的主页 yk_peng | 初学一级 | 园豆:-3
提问于:2014-09-21 21:58
< >
分享
最佳答案
0
#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位是字节位还是整数位?从你的描述好像是输入的整数位,但你提供的代码是字节位。

代码解释:

收获园豆:20
519740105 | 大侠五级 |园豆:5810 | 2014-09-22 08:58

k位是整数位了。这也就是我不理解他的代码的原因哦

yk_peng | 园豆:-3 (初学一级) | 2014-09-22 09:00

@yk_peng: 如果k位值的是整数,那么代码:

t<<=k

要修改为

t=10^k(也就是你的pow函数功能)。

519740105 | 园豆:5810 (大侠五级) | 2014-09-22 09:02

@yk_peng: 

另外:

既然k位不相等(k不大于8),那么,题目要求输入不大于10000的数字~~~其实意思就有点相悖了,所以,从出题人的本意是指二进制位 k 位,所以也就有了这段代码,只是出题人也没把意思描述清楚。

519740105 | 园豆:5810 (大侠五级) | 2014-09-22 09:03

@519740105: 你应该是和我一样想的。可是他的代码也是Accepted的,会不会是我没理解到他的意思

yk_peng | 园豆:-3 (初学一级) | 2014-09-22 09:04

@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 | 园豆:-3 (初学一级) | 2014-09-22 09:09

@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 | 园豆:5810 (大侠五级) | 2014-09-22 09:10

@519740105: 没有了,C的语法我都吃烂了。。。

yk_peng | 园豆:-3 (初学一级) | 2014-09-22 09:12

@yk_peng: 还纠结?给出的示例代码正确是在于k位是基于二进制的,而我们的理解都基于十进制了。题目描述有不明确的地方。

519740105 | 园豆:5810 (大侠五级) | 2014-09-22 09:16
其他回答(3)
0

t<<=k;这步你单步跟踪就可以知道t变成多少了。

printf("%d\n",(a-b)%t?a+b:-1);

如果后面K位相同的话, (a-b)%t应该=0,也就是TRUE,显示结果a+b,否则显示-1

收获园豆:5
爱编程的大叔 | 园豆:30844 (高人七级) | 2014-09-21 22:20

我就是不理解这句嘛:后面K位相同的话, (a-b)%t应该=0

支持(0) 反对(0) yk_peng | 园豆:-3 (初学一级) | 2014-09-21 22:23

用的位运算,看不懂。这样我知道 (a-b)%pow(10, k)==0

支持(0) 反对(0) yk_peng | 园豆:-3 (初学一级) | 2014-09-21 22:25

@yk_peng: 几个情况补充一下

1、我不清楚你写的答案对不对。

2、我知道那是位运算,但感觉位运算是2进制的,而不是10进制的,太久没有看C了,不清楚。你那样用POW函数肯定是没有错的。

3、对我来说,大概知道原理就够了,不追求细节正确(这个调试阶段可以搞定)。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30844 (高人七级) | 2014-09-21 22:33

@爱编程的大叔: 我就是不知道,他用这个位运算的原理了。

这是我的代码,用的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的

支持(0) 反对(0) yk_peng | 园豆:-3 (初学一级) | 2014-09-21 22:42
0

我不是说你看不看得懂我写的,我写出来肯定是为了让人看懂的,我说的是你不看原理只看答案,就这样吧

飞鸿眉敛 | 园豆:256 (菜鸟二级) | 2014-09-22 10:58
0

原理就是如果两个数a和b的最后k位相同,那么a-b肯定能被10的(k)次方整除。

如:522-22=500能被10^2整除。

至于你代码里面的用的1来左移,我想是因为对于10^k总是能被2^k整除吧。

收获园豆:25
幻天芒 | 园豆:37205 (高人七级) | 2014-09-23 12:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册