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

老题新解|大整数加法

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

求两个不超过200位的非负整数的和。
输入:
有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。
输出:
一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输
出为0342。
样例输入:
22222222222222222222
33333333333333333333
样例输出:
55555555555555555555

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

一、题意分析

本题要求对两个不超过 200 位 的非负整数进行加法运算。由于数值范围远超 long long 的表示能力,因此我们不能使用普通整数类型,而应当使用字符数组 + 整数数组的方式来模拟手工加法。

输入两个不超过 200 位的非负整数,输出它们的和。
不能使用普通整型运算,而要自己用数组来模拟加法的全过程。

所以使用 char 数组 albl 来存放输入的两个大数。

由于 cin 不能直接读超长整数,这里用 gets() 读入整行字符串(虽然不安全,但在竞赛中常用来快速处理输入)。

读入后,通过:

la = strlen(al);
lb = strlen(bl);

得到两个字符串的长度,即数字的位数。

程序将字符串反向存入整数数组:

for (int i = 0; i <= la - 1; ++i) 
{a[la - i - 1] = al[i] - 48;
}

举个例子,输入 "123" → 存入数组后顺序为 a[0]=3, a[1]=2, a[2]=1 ,即数组中低位在前,高位在后,便于从个位开始做加法。

这样设计的好处是:
可以像我们在纸上竖式加法那样,从个位向高位逐位累加。

二、完成代码

(1)定义变量

int a[2000], b[2000], c[2000];
char al[2000], bl[2000];

三个整数数组分别存放第一个数、第二个数及结果。
两个字符数组存放输入的字符串。

(2)处理输入

gets(al); gets(bl);
la = strlen(al);
lb = strlen(bl);

此处 gets 读入字符串,strlen 计算其长度。

(3)反向存储

for (int i = 0; i <= la - 1; ++i) a[la - i - 1] = al[i] - 48;
for (int i = 0; i <= lb - 1; ++i) b[lb - i - 1] = bl[i] - 48;

这里的 -48 是因为字符 '0' 的 ASCII 值为 48,
减去 48 就可以把字符转为真正的数字。

(4)按位相加

lc = 1; // 从个位开始
while (lc <= la || lc <= lb)
{c[lc] = a[lc] + b[lc] + x;  // 当前位相加x = c[lc] / 10;             // 判断是否产生进位c[lc] %= 10;                // 当前位只保留个位lc++;                       // 移动到下一位
}

这里模拟了“手算加法”的核心步骤:

  • 两数同位相加;
  • 加上进位 x
  • 计算新的进位;
  • 再继续下一位。

(5)处理最后进位

c[lc] = x;

如果最后一位相加后仍然有进位,就写入结果的最高位。

(6)去掉前导零

`while (c[lc] == 0 && lc > 1) lc--;`

防止输出类似 000123 的格式。只保留最左边的有效位。

(7)倒序输出

for (int i = lc; i >= 1; --i)cout << c[i];
cout << endl;

因为之前是反向存储的,现在倒序输出即可得到正确顺序。

按照样例输入对数据进行验证。

符合样例输出,到网站提交测评。

测试通过!

三、完整代码

该题的完整代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;int a[2000], b[2000], c[2000];
char al[2000], bl[2000];int main()
{int la, lb, lc, x = 0;gets(al); gets(bl);                  // 读入两个超长整数la = strlen(al); lb = strlen(bl);    // 获取两数长度for (int i = 0; i <= la - 1; ++i) a[la - i - 1] = al[i] - 48;for (int i = 0; i <= lb - 1; ++i) b[lb - i - 1] = bl[i] - 48;lc = 1;                              // 从个位开始while (lc <= la || lc <= lb)         // 逐位相加{c[lc] = a[lc] + b[lc] + x;       // 加上进位x = c[lc] / 10;                  // 计算新的进位c[lc] %= 10;                     // 当前位取个位lc++;                            // 移动到下一位}c[lc] = x;                           // 处理最后的进位while (c[lc] == 0 && lc > 1) lc--;   // 去掉前导零for (int i = lc; i >= 1; --i) cout << c[i];cout << endl;return 0;
}

四、总结

这道大整数加法题重点考察的是:

1、大数表示方法:用数组按位存储大数,每个数组元素保存一位(0~9),这样规避了语言内建数值范围的限制。

2、字符串与数字互转:输入为字符串,需要把字符 '0'~'9' 转换为整数 0~9,以便按位运算。

3、按位加法与进位处理:按位相加并保存进位是核心逻辑,循环要覆盖两个数长度的最大值,最后别忘了处理最高位的进位。

4、输出时去掉前导 0:相加结果不能包含多余的前导 0,输出前需确定最高非零位的位置。

5、代码规范与安全:建议使用 stringcin/getline 代替 gets,并保持数组下标约定的一致性与可读性。

这类题目是学习数组、字符串和基础算法思想的经典训练题,熟练掌握对今后处理大数问题(乘法、减法、进位/借位问题等)非常有帮助。

---end---

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

我们下集见~

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

相关文章:

  • 常见python 排序
  • windows安装claude踩到的坑
  • 专业外贸网站建设公司价格深圳谷歌seo推广
  • 为什么需求文档总是不完整,有哪些解法
  • 88-python电网可视化项目-8-2
  • 计算机专业可考证书汇总及建议
  • 爱站网是干嘛的网站建设中 页面
  • 【agent】AI 数字人构建2:MDM与MNN
  • 配电安全“隐形哨兵”上线!RCMX-ONE剩余电流监视器,守护每一度电的安心
  • 视频封面制作网站wordpress怎么考别人的
  • 专做眼镜的网站临城网络营销怎么做
  • Oracle VirtualBox异常关闭后无法启动解决办法
  • 微信小程序开发从零基础到项目发布的全流程实战教程(五)
  • 边缘计算双雄:CDN与PCDN
  • LeetCode 面试经典 150_哈希表_存在重复元素 II(46_219_C++_简单)
  • 网站2个页面做首页广元 网站建设
  • HTML应用指南:利用POST请求获取全国中信银行网点位置信息
  • 加油站小程序上线即闲置?3 大核心功能 + 运营落地策略
  • 做淘宝客导购网站宁夏百度公司
  • 使用 Flask 实现本机 PyTorch 模型部署:从服务端搭建到客户端调用
  • sql题目练习——多表查询
  • c 做网站加载多个图片网站开发实战第二章
  • 精通C语言(3. 自定义类型:联合体和枚举)
  • 认知事物的三个层次
  • 做数学题目在哪个网站好设计好的装修公司
  • 09.Linux环境变量
  • 11、规划过程组(4):风险
  • HT8698 立体声 D 类音频功率放大器:性能参数介绍
  • 做亚克力在那个网站上好上海建工一建集团有限公司
  • DOM与BOM核心用法解析