top1编程
← 返回题目
题解

部分数字的减法

1 条题解

  • 0
    @ 2026-8-3 18:17:33

    解题思路

    题目要我们先从两个大整数里截取第 l 位到第 r 位,再计算这两段的差。因为位数最多有 100 位,直接按整数存会溢出,所以还是用高精度减法。

    整体分四步:

    1. 截取:用字符串下标直接取出第 l~r 位,得到两段数字。
    2. 比大小:两段位数相同,从高位往低位比较,判断结果的正负。
    3. 相减:把数字倒着存进数组(个位在最前),逐位相减,不够减就向高一位借 1。
    4. 去前导 0:如果差的前面是 0(比如 12345-12300 得到 45),输出时要跳过这些 0。

    如果第一个数截出来的比第二个小,结果就是负数,先输出负号,再用较大的减较小的。

    参考代码

    #include <iostream>
    using namespace std;
    
    char s1[105], s2[105];  // 两个大整数(用字符串读入)
    int a[105], b[105];     // 截取出来的两段数字,个位放在下标0
    int ans[105];           // 减法结果
    
    int main() {
        int l, r;
        cin >> s1;          // 第一个大整数
        cin >> s2;          // 第二个大整数
        cin >> l >> r;      // 截取第l位到第r位
    
        int len = r - l + 1;   // 截取出来的长度
    
        // 取出两个大整数的第l到r位
        char t1[105], t2[105];
        for (int i = 0; i < len; i++) {
            t1[i] = s1[l - 1 + i];
            t2[i] = s2[l - 1 + i];
        }
        t1[len] = 0;
        t2[len] = 0;
    
        // 比较两段数字谁更大(0相同,1第一个大,-1第二个大)
        int cmp = 0;
        for (int i = 0; i < len; i++) {
            if (t1[i] != t2[i]) {
                cmp = (t1[i] > t2[i]) ? 1 : -1;
                break;
            }
        }
    
        // 把数字倒着存进数组,个位放最前面,方便借位
        for (int i = 0; i < len; i++) {
            a[i] = t1[len - 1 - i] - '0';
            b[i] = t2[len - 1 - i] - '0';
        }
    
        // 如果第二个数更大,结果是负数:先输出负号,再反过来大减小
        if (cmp < 0) {
            cout << "-";
            for (int i = 0; i < len; i++) {
                int t = a[i];
                a[i] = b[i];
                b[i] = t;
            }
        }
    
        // 逐位相减,不够减就向高一位借1
        for (int i = 0; i < len; i++) {
            ans[i] += a[i] - b[i];
            if (ans[i] < 0) {
                ans[i] += 10;
                ans[i + 1] -= 1;
            }
        }
    
        // 去掉结果开头的0(比如12345-12300得到的45,前面的0不要)
        int pos = len - 1;
        while (pos > 0 && ans[pos] == 0) pos--;
    
        // 从高位到低位输出
        for (int i = pos; i >= 0; i--) {
            cout << ans[i];
        }
        return 0;
    }
    

    复杂度分析

    截取出的两段长度为 len,只需要扫一遍,时间复杂度是 O(len);几个长度相等的数组,额外空间复杂度也是 O(len)。

    • 1