杭电ACM 2057: A + B Again

原创作品 转载请注明出处http://blog.csdn.net/always2015/article/details/45791789

这里写图片描述

思路:
一看到这一道题我的直接思维是:把十六进制转化成十进制,然后十进制转化成十六进制输出,但是发现这样做有点绕,实现起来是有点难度的,最初也是用了这一种方式做了,花了比较长的时间,但是也AC了。。。下面首先我先讲解我用上述方法的解题思路,然后再讲解另一个简单的方法。其实计算机自己就会执行十六进制的运算,只不过的不能直接输出题目所要求那样的负数,不信的话自己也可以试试复数的十六进制输出结果。所以当结果为负数时候,为了得到题目所要求的需要自己转化。。。

题上说的A 和B 的长度不超过15,因为A和B 是十六进制数,如果长度不考虑正负号的话,一个数字表示4位二进制数,所以A 、B的位数是60位,所以定义A、B时,要定义为64位。当然如果考虑正负号的话,A、B含有的的数字最多为14个,这时,A、B的位数为56位,当然还要定义成64位的。。然后,把A和B相加,当然还是十六进制的数,赋值给B,判断B是不是负数,如果是负的,需变成正的,输出时,添个负号即可。。。所以在本代码中定义A,B两个数需要时long long 型或者__int64,对于long long 和__int64的区别可以查看http://blog.csdn.net/shiwei408/article/details/7463476,在这道题中两个都可以,但是在最后输出时候,long long 格式输出需要写成“%llX”而__int64需要写成“%I64X”。

还有注意一个细节:%X 或者是%x,可以直接输出十六进制的数字(大写的X,则对应大写的输出,例如A、B、…..。同理,小写的x对应小写的输出),我的第一种AC代码如下:

#include <iostream>
#include<string>
#include<math.h>
#include<stdio.h>
#include<string.h>
using namespace std;

int main(void)
{
    string a,b;
    __int64 int_a=0,int_b=0;
    int a_length,b_length,a_symbol,b_symbol;

    while(cin>>a>>b)
    {
        //取符号
        if(a[0]!='-')
            a_symbol=1;
        else
            a_symbol=-1;

        if(b[0]!='-')
            b_symbol=1;
        else
            b_symbol=-1;

        //获取长度
        a_length=a.size();
        b_length=b.size();

        //将a转换为十进制
        for(int i=0; i<a_length; i++)
        {
            //碰到符号就跳过
            if(a[i]=='-'||a[i]=='+')
                continue;
            //当大于10的十六进制时候的转化
            if(a[i]>='A'&&a[i]<='F')
                int_a+=((a[i]-'A')+10)*(__int64)pow(16.0,a_length-i-1);
            else if(a[i]>='a'&&a[i]<='f')
                int_a+=((a[i]-'a')+10)*(__int64)pow(16.0,a_length-i-1);
            else//小于10的十六进制的转化
                int_a+=(a[i]-'0')*(__int64)pow(16.0,a_length-i-1);
        }
         //将b转换为10进制
        for(int j=0; j<b_length; j++)
        {
            //碰到符号就跳过
            if(b[j]=='-'||b[j]=='+')
                continue;
            //当大于10的十六进制时候的转化
            if(b[j]>='A'&&b[j]<='F')
                int_b+=((b[j]-'A')+10)*(__int64)pow(16.0,b_length-j-1);
            else if(b[j]>='a'&&b[j]<='f')
                int_b+=((b[j]-'a')+10)*(__int64)pow(16.0,b_length-j-1);
            else//小于10的十六进制的转化
                int_b+=(b[j]-'0')*(__int64)pow(16.0,b_length-j-1);
        }

        //求a,b的和运算
        __int64 d=a_symbol*int_a+b_symbol*int_b;

        //注意结果为负数的时候所要输出结果和计算机计算结果有不同
        if(d>=0)
            printf("%I64X\n",d);
        else
            printf("-%I64X\n",-d);
        //重新初始化
        int_a=0;
        int_b=0;
    }

    return 0;
}

确实上面的这个方法有点繁琐。下面我来介绍另一种简单方法。其实在计算机中是可以进行十六进制的加减运算的,所以这就可以直接输入十六进制进行运算,所需要注意的问题和上述的一样,下面我就先来看C语言下的AC代码:

#include<stdio.h>
int main()
{
    __int64  A,B;
    while(scanf("%I64X %I64X",&A,&B)!=EOF)
    {
        B=A+B;
        if(B>=0)
            printf("%I64X\n",B);
        if(B<0)
        {
            B=-B;
            printf("-%I64X\n",B);
        }
    }
    return 0;
}

而且C++也是可以这么写的:c++中一般我们的输入都是十进制的,要输入其它类型的数据:(n是申明的变量)
cin>>oct>>n; 输入八进制
cin>>hex>>n; 输入十六进制.
AC代码如下:

#include <iostream>
#include<stdio.h>
using namespace std;

int main()
{
    long long A,B;
    while(cin>>hex>>A>>B)
    {
        B=A+B;
        if(B>=0)
        printf("%I64X\n",B);
        else
        {
            B=-B;
            printf("-%llX\n",B);
        }
    }
    return 0;
}

看了上述代码可能会有人有疑问:C++最后输出也可以用C++的格式输出啊如:

cout.setf(ios::showbase);//设置输出时的基数符号
cout.unsetf(ios::dec);//终止10进制的格式设置,因为编译器默认的10进制输出
cout.setf(ios::hex);//y设置以16进制输出
cout<<a<<endl;//16进制输出a

上述确实能输出十六进制a,但是他的输出格式为:0x…,前面带有十六进制标志的,不是我们所要的输出结果,不过也可以转化,在这里我就直接使用C的格式输出了。

比较这几种方式的,当然是最后两种最简单了。第一种可以让你更加清楚理解十六进制的与十进制的转换。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值