【题目】
CSP-S 2023 提高级 第一轮(初赛) 阅读程序(1)
#include <iostream>
using namespace std;
unsigned short f(unsigned short x) {
x ^= x << 6;
x ^= x >> 8;
return x;
}
int main() {
unsigned short x;
cin >> x;
unsigned short y = f(x);
cout << y << endl;
return 0;
}
假设输入的 x 是不超过 65535 的自然数,完成下面的判断题和单选题:
判断题
1.当输入非零时,输出一定不为零。()
2.将 f 函数的输入参数的类型改为 unsigned int,程序的输出不变。()
3.当输入为 65535 时,输出为 63。()
4.当输入为 1 时,输出为 64。()
单选题
5.当输入为 512 时,输出为()。
A. 33280
B. 33410
C. 33106
D. 33346
6.当输入为 64 时,执行完第 5 行后 x 的值为()。
A. 8256
B. 4130
C. 4128
D. 4160
【题目考点】
1. 位运算
位运算优先级:左移>>,右移<<运算符优先级高于按位与&,按位或|,以及按位异或^运算符
【解题思路】
unsigned short是两字节16位机器数
f函数的操作为:
首先x变为x异或x左移6位的结果。
而后x变为x异或x右移8位的结果。
输入的x不超过65535,说明输入的数字在unsigned short可以表示的数字范围内。
【试题答案及解析】
判断题
1. 当输入非零时,输出一定不为零。()
答:T
假设输出结果为0,那么第二步x ^ x>>8
结果为0
由于x>>8
的高8位为0,0^0=0
,因此x的高8位也为0。
而x的高8位是x>>8
的低8位,该问题中机器数都是16位,所以x>>8
每位都是0。
要想使x ^ x>>8
结果为0,那么x每位都为0。
那么x ^ x<<6
的结果为0
由于x<<6
的低6位为0,为了保证结果为0,那么x的低6位也为0。
x的低6位为0,那么x<<6
的第7到12位为0,那么x的第7到12位也为0。
那么x<<6
的第13到第16位为0,那么x的第13到16位为0。
所以x的值为0。
因此如果输出为0,则输入一定为0。
其逆否命题为:如果输入不为0,则输出一定不为0。该题描述正确。
2. 将 f 函数的输入参数的类型改为 unsigned int,程序的输出不变。()
答:F
如果改为unsigned int,则该题中的机器数都是32位机器数。
对于某些高位有1的情况,如果x是16位机器数,x<<6
会溢出,再进行x>>8
高8位一定为0。
而如果x是32位机器数,x<<6
不会溢出,再进行x>>8
高8位可能不为0。
由于一些计算过程中机器数中的1比较少,表示一个机器数可以不用写出机器数的每一位,只需要标出其有1的位置即可。比如第i位(从0开始数)有1,就可以写1<<i
,第i位和第j位有1可以记为1<<i | 1<<j
例:输入的x是32768,也就是1<<15
如果是16位机器数
计算 | 结果 |
---|---|
x | 1<<15 |
x<<6 | 0 |
x = x ^ x<<6 | 1<<15 |
x>>8 | 1<<7 |
x = x ^ x>>8 | 1<<15 | 1<<7 |
如果是32位机器数
计算 | 结果 |
---|---|
x | 1<<15 |
x<<6 | 1<<21 |
x = x ^ x<<6 | 1<<21 | 1<<15 |
x>>8 | 1<<13 | 1<<7 |
x = x ^ x>>8 | 1<<21 | 1<<15 | 1<<13 | 1<<7 |
二者结果不同
- 当输入为 65535 时,输出为 63。()
答:T
65535是 2 16 − 1 2^{16}-1 216−1,作为16位无符号机器数就是16个1
计算 | 结果 |
---|---|
x | 1111 1111 1111 1111 |
x<<6 | 1111 1111 1100 0000 |
x = x ^ x<<6 | 0000 0000 0011 1111 |
x>>8 | 0000 0000 0000 0000 |
x = x ^ x>>8 | 0000 0000 0011 1111 |
结果是111111,是 2 6 − 1 = 63 2^6-1=63 26−1=63
- 当输入为 1 时,输出为 64。()
答:F
计算 | 结果 |
---|---|
x | 1 |
x<<6 | 1<<6 |
x = x ^ x<<6 | 1 | 1<<6 |
x>>8 | 0 |
x = x ^ x>>8 | 1 | 1<<6 |
结果为: 1 + 2 6 = 65 1+2^6=65 1+26=65
单选题
6. 当输入为 512 时,输出为()。
A. 33280
B. 33410
C. 33106
D. 33346
答:B
512
=
2
9
512=2^9
512=29,其机器数为1<<9
计算 | 结果 |
---|---|
x | 1<<9 |
x<<6 | 1<<15 |
x = x ^ x<<6 | 1<<9 | 1<<15 |
x>>8 | 1<<1 | 1<<7 |
x = x ^ x>>8 | 1<<15 | 1<<9 | 1<<7 | 1<<1 |
2 15 + 2 9 + 2 7 + 2 1 = 32768 + 512 + 128 + 2 = 33410 2^{15}+2^9+2^7+2^1=32768+512+128+2=33410 215+29+27+21=32768+512+128+2=33410,选B。
- 当输入为 64 时,执行完第 5 行后 x 的值为()。
A. 8256
B. 4130
C. 4128
D. 4160
答:D
64 = 2 6 64=2^6 64=26,其机器数为1<<6
计算 | 结果 |
---|---|
x | 1<<6 |
x<<6 | 1<<12 |
x = x ^ x<<6 | 1<<12 | 1 << 6 |
2 12 + 2 6 = 4096 + 64 = 4160 2^{12}+2^6=4096+64=4160 212+26=4096+64=4160,选D