题目链接 :https://www.luogu.com.cn/problem/P1303
一、题目简介
题目描述
给定两个非负整数,求两个数的乘积。两个整数的数值范围极大,远超普通整型、长整型的存储范围,是经典的高精度乘法模板题。
输入格式
输入共两行,每行输入一个非负整数。
输出格式
输出两个数相乘后的结果,为一个非负整数。
输入输出样例
输入
1
2
输出
2
二、解题思路详细分析
1、问题难点
普通的 C++ 整型(int)、长整型(long long)存储空间有限,无法存储题目中极大的大数,直接使用 * 乘法运算符会出现溢出、数据错误。因此必须使用高精度算法,模拟人工竖式乘法完成运算。
2、高精度乘法核心原理(竖式模拟)
我们日常手写乘法竖式,就是高精度乘法的核心逻辑,算法完全模拟人工计算步骤:
- 倒序存储数字:将输入的字符串大数反转,让数字低位在前、高位在后,方便从低位开始逐位相乘、处理进位,避免数组下标越界和错位问题。
- 逐位相乘累加:双重循环遍历两个大数的每一位,根据竖式乘法规则:a 数组第 i 位 × b 数组第 j 位,结果累加到答案数组第 i+j 位。
- 统一处理进位:所有位相乘结束后,遍历答案数组,将每一位的数值对 10 取余保留当前位,除以 10 的结果作为进位传递到高一位。
- 去除前导零:运算完成后,答案数组高位可能存在多余的 0,需要清空前导零,特殊处理乘积为 0 的情况。
3、图文逻辑演示
举个例子:计算 12 × 34
- 原数字:a=12、b=34
- 倒序存储:a=2,1、b=4,3
- 逐位相乘规则:
- i=0(2)、j=0(4) → 结果存入 ans0
- i=0(2)、j=1(3) → 结果存入 ans1
- i=1(1)、j=0(4) → 结果存入 ans1
- i=1(1)、j=1(3) → 结果存入 ans2
- 累加完成后统一进位,最后倒序输出,得到最终结果 408,完全匹配竖式计算结果。
4、算法复杂度分析
设两个大数长度分别为 n、m,算法时间复杂度为 O(n×m),对于本题的数据范围完全够用,是高精度乘法最基础、最通用的模板写法。
三、AC 代码(超详细注释)
cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
// 设定最大数组长度,满足题目大数范围
const int MAXN = 2010;
// 定义数组存储大数,初始值默认为0
int a[MAXN], b[MAXN], ans[MAXN];
int main() {
// 1. 以字符串形式读取两个大数(解决大数无法用整型存储问题)
string s1, s2;
cin >> s1 >> s2;
// 获取两个数字的长度
int len1 = s1.size();
int len2 = s2.size();
// 2. 将字符串倒序转换为数字数组(低位在前,方便计算)
for(int i = 0; i < len1; i++)
a[i] = s1[len1 - i - 1] - '0'; // 字符转整型
for(int i = 0; i < len2; i++)
b[i] = s2[len2 - i - 1] - '0';
// 3. 高精度核心:逐位相乘累加
// a的第i位 * b的第j位,结果累加到ans[i+j]
for(int i = 0; i < len1; i++) {
for(int j = 0; j < len2; j++) {
ans[i + j] += a[i] * b[j];
}
}
// 4. 统一处理每一位的进位
// 最大乘积长度为 len1+len2,遍历所有位
for(int i = 0; i < len1 + len2; i++) {
if(ans[i] >= 10) { // 当前位数值大于等于10,需要进位
ans[i + 1] += ans[i] / 10; // 高位累加进位值
ans[i] = ans[i] % 10; // 当前位保留个位数字
}
}
// 5. 去除前导零:找到结果的最高位
int pos = len1 + len2 - 1;
// 从最高位向下遍历,跳过前导零,保留有效数字
while(pos > 0 && ans[pos] == 0)
pos--;
// 6. 从高位到低位倒序输出结果
for(int i = pos; i >= 0; i--)
cout << ans[i];
return 0;
}
四、代码核心细节讲解
1、倒序存储的意义
人工计算从低位开始,倒序存储后数组下标从小到大对应数字从低位到高位,进位只需要向下标 +1 的位置传递,逻辑简单、不易出错。
2、乘积下标规律
这是高精度乘法的核心公式:a[i] × b[j] → ans[i+j],完美对应竖式乘法的错位累加规则,是算法的核心精髓。
3、前导零处理
必须保留 pos > 0 的判断,避免两个数相乘为 0 时,将唯一的 0 也删除,导致无输出的错误。
五、总结
本题是高精度乘法万能模板题,掌握本题代码可以解决所有基础大数乘法问题。核心记住三个关键点:倒序存储、错位累加、统一进位、去除前导零。该模板代码简洁、效率稳定,可直接复用在各类 OI、算法竞赛的大数乘法题型中。