A*B Problem
题目背景
高精度乘法模板题。
题目描述
给出两个非负整数,求它们的乘积。
输入格式
输入共两行,每行一个非负整数。
输出格式
输出一个非负整数表示乘积。
样例 1
样例输入 1
1
2
样例输出 1
2
说明/提示
每个非负整数不超过 102000。
思路分析
-
读取输入:首先,我们需要从标准输入中读取两个非常大的整数。由于这些整数可能非常大,我们不能直接将它们存储在整型变量中,因此我们将它们作为字符串读取。
-
初始化数组:我们创建三个数组
a
、b
和c
来分别存储两个输入数的每一位(从低位到高位)以及它们的乘积的每一位。注意,数组的第一个元素(索引为0)用来存储数字的位数,方便后续计算。 -
将字符串转换为数组:由于我们从字符串中读取了数字,我们需要将它们转换为整数并存储在数组中。同时,我们注意到字符串中的数字是从高位到低位存储的,而我们在计算乘法时需要从低位到高位进行,因此我们需要将字符串中的数字反转后存储在数组中。
-
计算乘积:我们采用模拟手工乘法的方式来计算两个大数的乘积。对于
a
中的每一位与b
中的每一位相乘,将结果累加到c
数组的相应位置,并处理进位。 -
处理进位:在累加过程中,
c
数组的某些位置可能会超过9,这时我们需要将超出的部分作为进位加到更高位上。 -
去除前导0:由于乘积的最高位可能是0(特别是当两个数中有0或者乘积较小且以0开始时),我们需要在输出结果之前去除这些前导0。
-
输出结果:最后,我们从高位到低位遍历
c
数组,并打印出每一位数字,从而得到两个大数的乘积。
示例代码
#include<bits/stdc++.h>
using namespace std;
// 定义存储输入数字的字符串和数组
char a1[50001], b1[50001];
int a[50001], b[50001], c[100001]; // c数组需要更大以容纳乘积的每一位
int main () {
cin >> a1 >> b1; // 读取两个大数
// 初始化数组长度
int lenA = strlen(a1), lenB = strlen(b1);
a[0] = lenA; b[0] = lenB; // 存储长度
// 将字符串转换为数组,并反转数字顺序
for (int i = 1; i <= lenA; i++) a[i] = a1[lenA - i] - '0';
for (int i = 1; i <= lenB; i++) b[i] = b1[lenB - i] - '0';
// 计算乘积
for (int i = 1; i <= lenA; i++) {
for (int j = 1; j <= lenB; j++) {
c[i + j - 1] += a[i] * b[j]; // 累加乘积到相应位置
}
}
// 处理进位
int lenC = lenA + lenB; // 乘积的最大可能长度
for (int i = 1; i < lenC; i++) {
if (c[i] > 9) {
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
}
// 去除前导0
while (lenC > 1 && c[lenC] == 0) lenC--;
// 输出结果
for (int i = lenC; i >= 1; --i) {
cout << c[i];
}
return 0;
}