用掩码取出低 16 位并左移,同时把高 16 位右移,再按位或合并。
OJ: luogu
题目 ID: P1100
难度:普及-
标签:位运算掩码python
创建: 2026-07-16 19:20
更新: 2026-10-07 10:17
题意
把一个 32 位无符号整数的高 16 位与低 16 位交换,输出新整数。
思路
number>>16 把高半部分移动到低位;number&0xFFFF 只保留低 16 位,再左移 16 位。两部分没有重叠,用按位或合并:
text
(number >> 16) | ((number & 0xFFFF) << 16)Python 知识
- 十六进制字面量
0xFFFF正好是 16 个二进制1。 &是按位与掩码,<<、>>是位移,|合并位段。- Python 整数没有固定 32 位,但输入范围保证上述结果与无符号 32 位运算一致。
- 一行表达式已完整表达算法,不需要额外函数。
/home/rainboy/mycode/hugo-blog/content/program_language/python/cpp_to_python_pitfalls.md:Python 与 C++ 固定位宽整数差异。
代码
python
number = int(input())
print((number >> 16) | ((number & 0xFFFF) << 16))cpp
/**
* P1100 高低位交换
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
unsigned int n;
scanf("%u", &n);
// 低 16 位左移、高 16 位右移,然后合并
unsigned int ans = (n >> 16) | (n << 16);
printf("%u\n", ans);
return 0;
}Pythonic 写法
位运算高低互换:
python
x = int(input())
print((x >> 16) | ((x & 0xFFFF) << 16))STL 写法
把整数装进 bitset<32> 后每一位都有确定的下标:下标 0 是最低位,下标 31 是最高位,于是「高 16 位」就是下标 16…31、「低 16 位」是下标 0…15。bits << 16 把低半段顶到高位、bits >> 16 把高半段落回低位,两段互不重叠,按位或合并就完成了交换,最后用 to_ulong() 转回十进制输出。和上面 main.cpp 直接对整数做掩码位移相比,这里不必手写 0xFFFF,位段的位置由下标直接说明;读入用 unsigned long long,因为输入可能达到 int 的范围。
对应的 cppbook 章节:bitset:一组二进制开关
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-07 00:22
* update_at: 2026-10-07 00:35
*/
// 这是 STL 写法:把 32 位整数装进 bitset<32>,用 (b << 16) | (b >> 16) 交换高低 16 位,
// 再用 to_ulong() 转回十进制输出。对应 cppbook 的《bitset:一组二进制开关》。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
unsigned long long number; // 输入可能达到 2^32-1,超过 int,所以用 unsigned long long 读入
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> number;
// bitset<32> 把整数摊成 32 个开关:下标 0 是最低位,下标 31 是最高位。
// 题面说的“前 16 位(高位)”正是下标 16..31,“后 16 位(低位)”是下标 0..15。
bitset<32> bits(number);
// 左移 16 位把低 16 位顶到高位,右移 16 位把高 16 位落回低位;
// 两段互不重叠,按位或合并就完成了交换。移出 32 位宽度的位直接丢弃,不影响结果。
bitset<32> swapped = (bits << 16) | (bits >> 16);
// 转回整数输出十进制。32 位值一定能被 unsigned long 表示,不会触发 overflow_error。
unsigned long answer = swapped.to_ulong();
cout << answer << '\n';
return 0;
}复杂度
固定次数位运算,时间和额外空间复杂度均为
总结
位段操作的标准步骤是“掩码取出、位移到位、按位或合并”。