题解 P1100 「高低位交换」

· · 题解

这道题可以使用位运算。

最开始用模拟做写了30行,但看到老师的代码只有不到10行,······

话不多说,贴代码

这是一条分割线

多年之后回来看自己的题解,觉得不多写点对不起排在第一位,于是重新补了一些内容

位运算

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。 ——摘自某百科

常用的几种位运算

当两个数在二进制下对应位数上1 时,得到的结果为 1.

当两个数在二进制下对应位数上有一个1 时,得到的结果为 1.

当两个数在二进制下对应位数上不相同时,得到的结果为 1.

将一个数在二进制下整体向左移位

将一个数在二进制下整体向右移位.

举个栗子:

7 = (00000111)_2 11 = (00001011)_2 7 \ \mathrm{and} \ 11 = (00000011)_2 = 3 7 \ \mathrm{or} \ 11 = (00001111)_2 = 15 7 \ \mathrm{xor} \ 11 = (00001100)_2 = 12 7<<1 = (00001110)_2 = 14 7>>1 = (00000011)_2 = 3

通常情况下,左移一位表示将这个数乘以2,右移一位表示将这个数除以2,向下取整.

然后,对于这份代码,其实所谓的万无一失是不必要的,因为在做左移或者右移的时候,多余的位数就已经自动溢出了,所以可以省略不写.

另外,关于 \texttt{0x0000ffff} 这样的以 \texttt{0x} 开头的数据,是十六进制表示法,每一位满 161,用 0 ~ \texttt{F} 表示.

对于这道题目,我们只需要将原数的后16位前移至新数的前16位,将原数的前16位前移至新数的后16位,这道题目就做完了。

话不多说,贴代码

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
    unsigned long long x;
    cin>>x;
    cout<<((x&0x0000ffff)<<16|(x&0xffff0000)>>16)<<endl;//万无一失的做法
}