#CSPJCSMN13. 普及组程序专项-变量,数组,模拟

普及组程序专项-变量,数组,模拟

CSP-J/S 位运算与数组边界专项训练(10题)

题目1:位运算变量跟踪(基础)

#include <iostream>
using namespace std;

int main() {
    int a = 12;  
    int b = 10; 
    
    int r1 = a & b;  
    int r2 = a | b;  
    int r3 = a ^ b; 
    int r4 = ~a;      
    int r5 = a << 2; 
    int r6 = b >> 1;  
    
    cout << r1 << " " << r2 << " " << r3 << endl;
    cout << r4 << " " << r5 << " " << r6 << endl;
    return 0;
}

选择题

  1. 程序输出的第一行三个数是( )。
    A. 8 14 6
    B. 8 12 6
    C. 12 14 6
    D. 8 14 10

  2. 表达式a & (a-1)的作用是( )。
    A. 将a最低位的1变为0
    B. 将a最高位的1变为0
    C. 计算a的平方
    D. 判断a是否为偶数

  3. 对于任意正整数x,x & 1的结果可以判断( )。
    A. x是否为2的幂
    B. x的奇偶性
    C. x是否大于0
    D. x的符号

题目2:数组边界与位运算

#include <iostream>
using namespace std;

int main() {
    int arr[8] = {0};
    
    for (int i = 0; i < 8; i++) {
        arr[i] = 1 << i;
    }
    
    int sum = 0;
    for (int i = 0; i <= 8; i++) { 
        if (i < 8) {
            sum += arr[i];
        }
        if (i > 0) {
            sum -= arr[i-1] & arr[i];
        }
    }
    
    cout << "sum = " << sum << endl;
    return 0;
}

判断题

  1. 第6行的循环正确设置了数组元素。 ( )
  2. 第10行的循环条件i <= 8会导致数组越界。 ( )
  3. 表达式arr[i-1] & arr[i]总是为0。 ( )

选择题 4. 程序运行后sum的值是( )。
A. 0
B. 255
C. 127
D. 不确定(可能崩溃)

  1. 如果将第6行改为arr[i] = 3 << i,那么arr[2]的值是( )。
    A. 4
    B. 8
    C. 12
    D. 16

题目3:大模拟 - 位图管理

#include <iostream>
#include <cstring>
using namespace std;

const int MAX_BLOCKS = 100;
unsigned int bitmap[MAX_BLOCKS / 32 + 1];

void setBlock(int pos) {
    int index = pos / 32;
    int bit = pos % 32;
    bitmap[index] |= (1 << bit);
}

bool checkBlock(int pos) {
    int index = pos / 32;
    int bit = pos % 32;
    return (bitmap[index] >> bit) & 1;
}

int main() {
    memset(bitmap, 0, sizeof(bitmap));
    
  
    setBlock(0);
    setBlock(31);
    setBlock(32);
    setBlock(63);
    
    int count = 0;
    for (int i = 0; i < 64; i++) {
        if (checkBlock(i)) {
            count++;
        }
    }
    
    cout << "设置的位数: " << count << endl;
    return 0;
}

判断题

  1. bitmap数组足够存储100个块的状态。 ( )
  2. setBlock函数使用|=操作设置特定位。 ( )
  3. checkBlock函数返回指定位置是否被设置。 ( )

选择题 4. 程序输出的结果是( )。
A. 2
B. 3
C. 4
D. 64

  1. 如果要将第pos位清零,应该使用( )。
    A. bitmap[index] &= ~(1 << bit)
    B. bitmap[index] |= ~(1 << bit)
    C. bitmap[index] ^= (1 << bit)
    D. bitmap[index] = bitmap[index] >> bit

题目4:变量跟踪 - 复杂位运算

#include <iostream>
using namespace std;

int main() {
    unsigned int x = 0x0F;  
    
    int a = (x >> 2) & 0x03;  
    int b = (x << 2) | 0x03;  
    int c = x ^ (~x);         
    int d = x & (x - 1);      
    
    cout << a << " " << b << " " << c << " " << d << endl;
    return 0;
}

选择题

  1. 变量a的值是( )。
    A. 0
    B. 1
    C. 2
    D. 3

  2. 变量b的值是( )。
    A. 63
    B. 60
    C. 15
    D. 3

  3. 变量d的值是( )。
    A. 14
    B. 13
    C. 12
    D. 11

  4. 表达式x & -x的结果是( )。
    A. 0
    B. 1
    C. 8
    D. 15

题目5:数组边界 - 循环移位

#include <iostream>
using namespace std;

void rotateLeft(int arr[], int n, int k) {
    k = k % n;
    int temp[k];
    
    // 保存前k个元素
    for (int i = 0; i < k; i++) {
        temp[i] = arr[i];
    }
    
    // 左移剩余元素
    for (int i = 0; i < n - k; i++) {
        arr[i] = arr[i + k];
    }
    
    // 恢复前k个元素到末尾
    for (int i = 0; i < k; i++) {
        arr[n - k + i] = temp[i];
    }
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    rotateLeft(arr, n, 2);
    
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    return 0;
}

判断题

  1. 函数能正确处理k大于n的情况。 ( )
  2. 第4行创建临时数组的大小是动态的,符合C++标准。 ( )
  3. 当k=0时,函数不会修改数组。 ( )

选择题 4. 程序输出的结果是( )。
A. 1 2 3 4 5
B. 3 4 5 1 2
C. 4 5 1 2 3
D. 5 1 2 3 4

  1. 如果输入n=5, k=7,实际移动的位数是( )。
    A. 0
    B. 2
    C. 5
    D. 7

题目6:大模拟 - 状态压缩枚举

#include <iostream>
using namespace std;

int main() {
    int n = 4;  
    int total = 1 << n; 
    
    for (int mask = 0; mask < total; mask++) {

        int size = 0;
        int temp = mask;
        while (temp) {
            size++;
            temp = temp & (temp - 1);
        }
        
        // 输出子集
        cout << "{";
        bool first = true;
        for (int i = 0; i < n; i++) {
            if (mask & (1 << i)) {
                if (!first) cout << ",";
                cout << (i + 1);
                first = false;
            }
        }
        cout << "} size=" << size << endl;
    }
    
    return 0;
}

判断题

  1. 程序会输出所有可能的子集,包括空集。 ( )
  2. 变量size统计子集中元素个数。 ( )
  3. 循环temp = temp & (temp - 1)用于统计temp中1的个数。 ( )

选择题 4. 当mask=5(二进制0101)时,输出的子集是( )。
A. {1,3}
B. {2,4}
C. {1,4}
D. {2,3}

  1. 程序总共会输出多少个子集?( )
    A. 8
    B. 16
    C. 32
    D. 64

题目7:变量跟踪 - 嵌套位运算

#include <iostream>
using namespace std;

int main() {
    unsigned char x = 0xAB; 
    
 
    x = x ^ 0xFF;      
    x = (x >> 2) & 0x3F;  
    x = x | 0xC0;    
    
    cout << hex << (int)x << endl;
    return 0;
}

选择题

  1. 执行x = x ^ 0xFF后,x的值是( )。
    A. 0x54
    B. 0xAB
    C. 0xFF
    D. 0x00

  2. 执行x = (x >> 2) & 0x3F后,x的值是( )。
    A. 0x15
    B. 0x3F
    C. 0x54
    D. 0x2A

  3. 程序最终输出的结果是( )。
    A. 0xD5
    B. 0xF5
    C. 0xFD
    D. 0xFF

  4. 表达式0x3F的二进制表示是( )。
    A. 00111111
    B. 11111100
    C. 11110000
    D. 00001111

题目8:数组边界 - 二维数组访问

#include <iostream>
using namespace std;

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    int sum = 0;
    
  
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            if ((i ^ j) == 0) { 
                sum += matrix[i][j];
            }
        }
    }
    
    cout << "sum = " << sum << endl;
    
  
    int val = matrix[2][4];  /
    cout << "val = " << val << endl;
    
    return 0;
}

判断题

  1. 第15行的条件(i ^ j) == 0等价于i == j。 ( )
  2. 程序计算的是矩阵主对角线上元素的和。 ( )
  3. 第22行访问matrix[2][4]一定会导致程序崩溃。 ( )

选择题 4. 变量sum的值是( )。
A. 6
B. 18
C. 15
D. 10

  1. 在C++中,访问越界数组元素通常会导致( )。
    A. 编译错误
    B. 运行时错误
    C. 未定义行为
    D. 返回0

题目9:大模拟 - 位运算加密

#include <iostream>
#include <string>
using namespace std;

string encrypt(string text, unsigned char key) {
    string result = text;
    
    for (size_t i = 0; i < text.length(); i++) {

        unsigned char c = text[i];
        c = c ^ key;               
        c = (c << 2) | (c >> 6);  
        c = c ^ 0xAA;             
        result[i] = c;
        
   
        key = (key << 1) | (key >> 7);
    }
    
    return result;
}

int main() {
    string message = "ABC";
    unsigned char key = 0x73;
    
    string encrypted = encrypt(message, key);
    
    cout << "加密结果长度: " << encrypted.length() << endl;
    cout << "第一个字符ASCII: " << (int)(unsigned char)encrypted[0] << endl;
    
    return 0;
}

判断题

  1. 加密函数对每个字符进行相同的变换。 ( )
  2. 密钥在每次加密后会更新。 ( )
  3. 循环左移操作(c << 2) | (c >> 6)可以正确处理8位字符。 ( )

选择题 4. 对字符'A'(ASCII 65)执行c ^ 0x73的结果是( )。
A. 0x16
B. 0x73
C. 0x65
D. 0x00

  1. 表达式(key << 1) | (key >> 7)实现的功能是( )。
    A. 将key乘以2
    B. 将key循环左移1位
    C. 将key右移1位
    D. 交换key的高低位

题目10:综合应用 - 位运算与数组

#include <iostream>
using namespace std;

int main() {
    const int N = 8;
    int data[N] = {0};
    

    for (int i = 0; i < N; i++) {
        data[i] = (i + 1) * ((i & 1) ? -1 : 1);
    }
    

    int result = 0;
    for (int i = 0; i < N; i++) {
        int val = data[i];
        
     
        int mask = val >> (sizeof(int) * 8 - 1);
        val = (val + mask) ^ mask;
        

        if (val & (1 << 2)) {  
            result |= (1 << i);
        }
    }
    
    cout << "result = " << result << endl;
    cout << "result的二进制: ";
    for (int i = 7; i >= 0; i--) {
        cout << ((result >> i) & 1);
    }
    cout << endl;
    
    return 0;
}

判断题

  1. 第9行根据i的奇偶性设置data[i]的正负号。 ( )
  2. 第19-20行通过位运算计算val的绝对值。 ( )
  3. 第23行检查val的第2位(从0开始)是否为1。 ( )

选择题 4. 初始化后,data[3]的值是( )。
A. 3
B. -3
C. 4
D. -4

  1. 程序输出的result的二进制表示是( )。
    A. 00001010
    B. 00010100
    C. 00101000
    D. 01010000