• P1100 高低位交换


    摘要:就是让你把一个数的二进制凑够32位然后从中间劈开交换,再转换成十进制。

    我一开始写这道题的时候,思路就是很暴力的把他们拆开,补零,交换转成10进制(用了好多字符串)。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    unsigned long long a,ans=0,sum=0,shi=0;
    string h,l,hh,ll,ha;//这是一堆字符串
    int main(){
        scanf("%u",&a);
        while(a>0){
            if(sum<16){//判断如果现在的位数小于16
                h[ans]=a%2+'0';//就把这个存在字符串h里面
            }
            if(ans==16){
                ans=0;//ans起到的是下标的作用
            }
            if(sum>=16){//判断如果现在的位数小于16
                l[ans]=a%2+'0';//就把这个存在字符串h里面
            }
            a/=2;
            ans++;
            sum++;
        }
        if(sum>=16&&ans<16){//补零
            for(int i=ans;i<16;i++){
                l[i]='0';//我也不知道我当时怎么想的,好像是觉得两个如果都没有满16,那就做两个判断,都补上零。
            }
        }
        if(sum<16&&ans<16){//依然是补零
            for(int i=ans;i<16;i++){
                h[i]='0';
            }
            for(int i=0;i<16;i++){
                l[i]='0';
            }
        }
        sum=0;//用字符串ha把他们两个交换着存过来
        for(int i=16-1;i>=0;i--){
            ha[sum]=h[i];
            sum++;
        }
        for(int i=16-1;i>=0;i--){
            ha[sum]=l[i];
            sum++;
        }
        ans=1;
        sum=0;
        int i=0;
        for(int i=32-1;i>=0;i--){//倒着把他们输出出来
            shi+=(ha[i]-'0')*ans;
            ans*=2;
        }
        printf("%u",shi);
        return 0;
    }

    结果很悲惨,不仅没A只得了90不说,我改来改去都把自己给改迷糊了。于是我就重新构思了一下,写了下面的代码,就AC了。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    unsigned long long n,shu[10010],ans=0,shi=0;
    int main(){
        scanf("%u",&n);
        while(n>0){//转二进制,没有用一个字符串,用的数组。因为数组不仅很方便,甚至连补零那一步都省了,因为数组它本身默认值就是0嘛,所以就可以直接转成十进制。
            shu[ans]=n%2;
            n/=2;
            ans++;
        }
        ans=1;
        for(int i=16;i<32;i++){
            shi+=shu[i]*ans;
            ans*=2;
        }//先把后面的16位转成10进制。
        for(int i=0;i<16;i++){
            shi+=shu[i]*ans;
            ans*=2;
        }//再把前面的16位转成10进制,记得要用一个变量,不然就变成两个数了
        printf("%u\n",shi);//最后输出就好啦
        return 0;
    }

    重写的代码:大致思路就是把转化成的二进制存到一个数组里(因为数组默认都是0,所以就直接省去补零这一步了,直接算就好了),一定要记得先算后面的再算前面的!!

    做完不久后我又知道了一个东西:左移和右移运算符(跟异或是一套的)

    仅仅只用几行就可以把这道题A掉。

    代码如下

    #include<iostream>
    #include<cstdio>
    int n;
    int main(){
        scanf("%d",&n);
        printf("%d\n",(n>>16)+(n<<16));
        //>>是把这个数转为二进制右移(而且他还会自动补零!!)
        //<<相反就是把这个数的二进制往左移喽(依然会自动补零)
        return 0;
    }

    加上注释一共10行,所以建议追求代码简洁的一定要去学学位运算,可以省去好多劲儿。

    虽然这个这么简单的代码把我写了好久的代码给秒杀了,但是我并不是很伤心,因为学会了这个以后肯定在别的地方可以用到。

    以上为我这道题的全部思路与解法,如果有什么不对的地方,还请各位大佬及时向我纠正。

  • 相关阅读:
    Windows更改默认RDP端口
    npm
    virtbuilder、oz
    brctl 详细使用
    Linux 精心设计的操作
    Oracle 11.2.0.1.0 CRS4639: Could not contact Oracle High Availability Services
    Oracle 11g 数据库启动时实例恢复的背后
    RHEL Debian Repository Configuration
    C#编码规范2
    .net二维码图片生成,并在中间添加LOGO,附base64图片下载功能
  • 原文地址:https://www.cnblogs.com/dgdger/p/12848928.html
Copyright © 2020-2023  润新知