CSP-S 2023 提高级 第一轮(初赛) 阅读程序(1)

【题目】

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位机器数

计算结果
x1<<15
x<<60
x = x ^ x<<61<<15
x>>81<<7
x = x ^ x>>81<<15 | 1<<7

如果是32位机器数

计算结果
x1<<15
x<<61<<21
x = x ^ x<<61<<21 | 1<<15
x>>81<<13 | 1<<7
x = x ^ x>>81<<21 | 1<<15 | 1<<13 | 1<<7

二者结果不同

  1. 当输入为 65535 时,输出为 63。()
    答:T
    65535是 2 16 − 1 2^{16}-1 2161,作为16位无符号机器数就是16个1
计算结果
x1111 1111 1111 1111
x<<61111 1111 1100 0000
x = x ^ x<<60000 0000 0011 1111
x>>80000 0000 0000 0000
x = x ^ x>>80000 0000 0011 1111

结果是111111,是 2 6 − 1 = 63 2^6-1=63 261=63

  1. 当输入为 1 时,输出为 64。()
    答:F
计算结果
x1
x<<61<<6
x = x ^ x<<61 | 1<<6
x>>80
x = x ^ x>>81 | 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

计算结果
x1<<9
x<<61<<15
x = x ^ x<<61<<9 | 1<<15
x>>81<<1 | 1<<7
x = x ^ x>>81<<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。

  1. 当输入为 64 时,执行完第 5 行后 x 的值为()。
    A. 8256
    B. 4130
    C. 4128
    D. 4160
    答:D
    64 = 2 6 64=2^6 64=26,其机器数为1<<6
计算结果
x1<<6
x<<61<<12
x = x ^ x<<61<<12 | 1 << 6

2 12 + 2 6 = 4096 + 64 = 4160 2^{12}+2^6=4096+64=4160 212+26=4096+64=4160,选D

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值