【洛谷刷题笔记】P1601 A+B Problem(高精):高精度加法
一、原题:
A+B Problem(高精)
题目描述
高精度加法,相当于 a+b problem,不用考虑负数。
输入格式
分两行输入。 a , b ≤ 1 0 500 a,b \leq 10^{500} a,b≤10500。
输出格式
输出只有一行,代表 a + b a+b a+b 的值。
样例 #1
样例输入 #1
1
1
样例输出 #1
2
样例 #2
样例输入 #2
1001
9099
样例输出 #2
10100
提示
20 % 20\% 20% 的测试数据, 0 ≤ a , b ≤ 1 0 9 0\le a,b \le10^9 0≤a,b≤109;
40 % 40\% 40% 的测试数据, 0 ≤ a , b ≤ 1 0 18 0\le a,b \le10^{18} 0≤a,b≤1018。
二、解决:
高精度计算(Arbitrary-Precision Arithmetic),也被称作大整数(bignum)计算,运用了一些算法结构来支持更大整数间的运算(数字大小超过语言内建整型)—摘自OI Wiki
1.存储:
在使用高精度计算时,我们常用字符串来保存。
定义char s1[500],s2[500],(500是为了防止越界,501,499都行)
而在实际操作时,我们需要反转存储,使数字的最低为就是下标最小的位置,同时使数字的相同权值位对齐,以便运算。
用数组a,b保存反转后的两组数,c[500]来保存结果。
特别注意,此时个位下标为1而非0;
代码如下:
char s1[500],s2[500];
int a[500],b[500],c[500];
//注意初始化
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
int la=0,lb=0,lc=0;
cin>>s1>>s2;
la=strlen(s1);
lb =strlen(s2);
//反转存储
for(int i =0;i<la;i++){
a[la-i]=s1[i]-'0';//将字符转为数字
}
for(int i =0;i<lb;i++){
a[lb-i]=s2[i]-'0';
}
2.计算:
首先计算输出结果的长度lc( 加一是为了计算a,b最大位相加后的进一)
而后逐位计算,特别注意“c[i]+=a[i]+b[i];”中的“+=”,是为了计算前一位计算时进的1。
lc = max(la, lb) + 1;
for(int i = 1;i<=lc;i++){
c[i]+=a[i]+b[i];//特别注意+=
c[i+1]=c[i]/10;
c[i]=c[i]%10;
}
3.输出:
首先判断输出的位数,即处理前导0;(&&lc>0是为了不删除结果为0的0)
后逐位输出(注意逆序)。
if (c[lc] == 0 && lc > 0)
lc--;
for (int i = lc; i > 0; i--) {
cout << c[i];
}
全部源代码
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int main() {
char s1[500], s2[500];
int a[500], b[500], c[500];
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
int la, lb, lc;
cin >> s1 >> s2;
la = strlen(s1);
lb = strlen(s2);
//反转存储
for (int i = 0; i < la; i++) {
a[la - i] = s1[i] - '0'; //将字符转为数字
}
for (int i = 0; i < lb; i++) {
b[lb - i] = s2[i] - '0';
}
lc = max(la, lb) + 1;
for (int i = 1; i <= lc; i++) {
c[i] += a[i] + b[i]; //特别注意+=
c[i + 1] = c[i] / 10;
c[i] = c[i] % 10;
}
if (c[lc] == 0 && lc > 0)
lc--;
for (int i = lc; i > 0; i--) {
cout << c[i];
}
}```