当前位置: 首页 > news >正文

老题新解|大整数减法

《信息学奥赛一本通》第165题:大整数减法

求两个大的正整数相减的差。
输入:共两行,第 1 行是被减数 aaa,第 2 行是减数 bbb(a>ba>ba>b)。每个大整数不超过 200 位,不会有多余的前导 0。
输出:一行,即所求的差。
例如输入:
99999999999999999999999999999999 99999999999 输出: 99999999999999999999999900000000

大家好,我是莫小特。
这篇文章给大家带来《信息学奥赛一本通》中的第 165 题:大整数减法。

一、题目描述

求两个大的正整数相减的差。
输入:共两行,第 1 行是被减数 aaa,第 2 行是减数 bbb(a>ba>ba>b)。每个大整数不超过 200 位,不会有多余的前导 0。
输出:一行,即所求的差。
例如输入:
99999999999999999999999999999999 99999999999
输出:99999999999999999999999900000000

二、题意分析

这是一道典型的“大整数运算”题目。由于输入的数字长度可达上百位,C++ 内置整数类型(如 int, long long)无法存储,所以要把字符串转换为按位存放的数组来模拟手算减法的过程(从低位到高位逐位相减并处理借位),最后把结果逆序输出并去掉多余的前导零。

常用步骤:

  1. 读入两个字符串 a(被减数),b(减数)。题目已保证 a > b,因此结果非负。

  2. 将两个字符串从右往左转换成整型数组(或直接按索引访问字符串字符并减去 '0'),便于做 “低位到高位” 的逐位运算。

  3. 用一个整型数组 c 存放差的各位,按位相减:c[i] = a[i] - b[i] - borrow。若不够(负数),则加上 10 并置 borrow = 1,否则 borrow = 0

  4. 最后数组 c 的最高位可能为 0,需要去掉前导 0(但结果为 0 时至少保留一位 0)。

  5. 输出时将 c 从高位到低位顺序打印。

三、完整代码

该题的完整代码如下:

#include <bits/stdc++.h>
using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);string a, b;if (!(cin >> a)) return 0;cin >> b;// 将字符串按位从最低位存到数组(下标 0 表示最低位)int lena = a.length();int lenb = b.length();vector<int> A(lena), B(lenb);for (int i = 0; i < lena; ++i) A[i] = a[lena - 1 - i] - '0';for (int i = 0; i < lenb; ++i) B[i] = b[lenb - 1 - i] - '0';// 结果数组,长度至少为 lenavector<int> C(lena, 0);int borrow = 0;for (int i = 0; i < lena; ++i) {int bi = (i < lenb) ? B[i] : 0;int diff = A[i] - bi - borrow;if (diff < 0) {diff += 10;borrow = 1;} else {borrow = 0;}C[i] = diff;}// 删除高位多余的 0(保留至少一位)int pos = lena - 1;while (pos > 0 && C[pos] == 0) --pos;// 输出从高位到低位for (int i = pos; i >= 0; --i) cout << C[i];cout << '\n';return 0;
}

四、代码详解(逐段说明)

  1. ios::sync_with_stdio(false); cin.tie(nullptr);
    加速输入输出,常用模板。

  2. 读入字符串 ab:两行输入分别保存被减数和减数。

  3. 将字符串反向存入整型数组 AB,方便从最低位(下标 0)开始运算:

    for (int i = 0; i < lena; ++i) A[i] = a[lena - 1 - i] - '0';

    这样 A[0] 是个位,A[1] 是十位,依次类推。

  4. vector<int> C(lena, 0); 为结果分配空间,长度至少为 lena(被减数的位数)。

  5. 主循环逐位相减并处理借位:

    int diff = A[i] - bi - borrow; if (diff < 0) { diff += 10; borrow = 1; } else borrow = 0; C[i] = diff;

    这里 bii >= lenb 时取 0(短数自动补 0)。

  6. 去掉高位多余的 0:

    int pos = lena - 1; while (pos > 0 && C[pos] == 0) --pos;

    保证当结果为 0 时依然输出单个 0

  7. pos0 逆序输出各位,得到最终结果字符串。

五、复杂度与注意事项

  • 时间复杂度 O(L),L 为被减数的位数(<=200),非常快。

  • 空间复杂度 O(L)。

  • 题目保证 a > b,所以无需考虑负数结果。但若题目不保证,需要额外比较字符串大小以决定符号输出。

  • 注意字符串长度差异,短的数要当作前面补 0 处理。

  • 注意去掉前导零,但结果为 0 时应输出单个 0

六、总结

这道题是训练字符串与数组模拟“大整数运算”的基础题,考察点包括:

  • 字符串与数字的互相转换(char - '0');

  • 低位到高位的逐位模拟(反向存储或逆序遍历);

  • 借位处理逻辑(若差小于 0 则加 10 并借 1);

  • 去掉结果的前导零。

常见错误

  1. 忘记短数补 0,导致越界或错误结果;

  2. 去掉所有高位 0(没保留至少一位),当结果为 0 时输出空行;

  3. 将字符串从前往后直接相减而未处理借位方向(容易出错)。

解题建议:用手算两个长数的减法模拟一次,体会借位传播的规则,然后按位实现;提交前多测试边界:ab 位数相等、b 很短、结果恰好有许多高位 0(需要去掉)以及 ab 相差一位等情况。

---end---

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注我哦!
如果有更好的方法也可以在评论区评论哦,我都会看哒~

我们下集见~

http://www.dtcms.com/a/465861.html

相关文章:

  • 品牌网官网查询外贸网站建设平台优化营销推广
  • 上海微信网站建设山东做网站建设的好公司排名
  • 记录一次巧妙的SQL:一对多关联导致的 sum () 、count()等group函数重复计算问题
  • 3.3 Function Calling实战
  • 无锡企业网站制作策划深圳海洋网络做网站
  • Maven 自动化部署
  • 阿里云做网站教程辽宁做网站找谁
  • Flutter中新手需要掌握的几种Widget
  • 分类算法-逻辑回归
  • MySQL Redo Log 和 Undo Log 满了会有什么问题
  • 从崩溃到稳定:如何用<limits>头文件解决C++数值处理的核心痛点?
  • 自定义tabs+索引列表,支持左右滑动切换
  • 建设网站的必要与可行性制作企业网站需要注意的事项
  • MySQL查询优化实战从慢查询到高性能的索引重构策略
  • 官方网站建设报价wordpress 在线咨询
  • 从零实现JSON与图片文件上传功能
  • 第五部分:VTK高级功能模块(第140章 Accelerators模块 - 加速器支持类)
  • 头条站长平台电商网站开发实训软件
  • 库卡机械臂的转角系统以及固定轴和欧拉角的计算方式
  • 机器学习高级-Chapter 04-概率论与贝叶斯分类
  • 站点搜索编程零基础入门课程
  • 网站焦点图如何美观python做网站怎么样
  • SQL百题斩:从入门到精通,一站式解锁数据世界
  • TMC2240步进电机驱动芯片寄存器配置和电路设计
  • 高通被调查市占率将降,昂瑞微IPO推动射频芯片自主创新
  • SQL SERVER从专家到小白
  • 温州市企业网站制作网站升级建设中
  • 开源安全管理平台wazuh-暴力破解检测与响应
  • 视频网站用虚拟主机织梦网站标题被篡改
  • VBA即用型代码手册:创建一个新文档并保存html文件