1 条题解

  • 0
    @ 2026-10-31 17:56:34

    思路

    题意:读入整数 n∈[−127,127]n\in[-127,127],输出它的 8 位二进制补码。

    核心观察

    固定位宽下的补码,与“先对 2bits2^{bits} 取模、再按无符号二进制展开”完全等价:

    • 当 n≥0n \ge 0 时,n&255=nn \mathbin{\&} 255 = n,二进制展开就是原码,也就是补码。
    • 当 n<0n < 0 时,n&255=n+256n \mathbin{\&} 255 = n + 256,最高位为 1,恰好等于“符号位不变、其余位取反再加 1”的结果。

    例如 −6&255=250=(11111010)2-6 \mathbin{\&} 255 = 250 = (11111010)_2,与按定义求出的补码一致。

    这样就不必分别处理正负两种情形,也不需要真的做取反加一。

    实现步骤

    1. 由位宽算出掩码 mask = 2^bits - 1;
    2. 令 val = n & mask,得到该位宽下的无符号值(负数在此步被转换成补码形式);
    3. 从第 bits-1 位到第 0 位,依次取 (val >> i) & 1 拼成 '0'/'1' 字符串;
    4. test(n) 用默认位宽 8 调用并输出结果。

    代码中 minv、maxv 只是记录该位宽能表示的数值范围,不参与实际计算。另外 bits == 64 时 1 << 64 属于未定义行为,所以掩码分支写成 0 作为占位;本题固定 8 位,不会走到该分支。

    复杂度

    时间 O(bits)=O(8)O(\text{bits}) = O(8),空间 O(bits)O(\text{bits}),与 nn 的大小无关。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    // 返回 n 的 bits 位补码(默认 8 位)
    string two_complement(int n, int bits = 8) {
        int minv = -(1 << (bits-1));        // 该位宽可表示的最小值(仅作记录,未参与计算)
        int maxv = (1 << (bits-1)) - 1;     // 该位宽可表示的最大值(仅作记录,未参与计算)
        // 低 bits 位全为 1 的掩码;64 位时 1<<64 未定义,用 0 占位(本题不会触发)
        int mask = (bits == 64) ? 0 : ((1 << bits) - 1);
        int val = n & mask;                 // 取模 2^bits,负数由此变成补码对应的无符号值
        string s;
        for (int i = bits-1; i >= 0; --i) {
            // 从高位到低位依次取二进制位
            s.push_back( (val >> i) & 1 ? '1' : '0' );
        }
        return s;
    }
    
    // 按题目要求输出 n 的 8 位补码
    void test(int n){
        string s = two_complement(n);
        cout << s << "\n";
    }
    
    int main() {
        int n;
        cin >> n;
        test(n);
    
        return 0;
    }
    
    • 1

    信息

    ID
    37
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    1
    已通过
    1
    上传者