高精度加法
问题描述
给定两个正整数(不含前导 0),计算它们的和。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的和。
数据范围
1≤整数长度≤100000
输入样例
12
23
输出样例
35
问题分析
计算 567 + 28
- 用 a, b 两个字符串存储输入。a = 567, b = 28
- 为了方便计算,将两个数分别 倒序 存放在 A, B 两个整数数组中。 A = [7, 6, 5], B = [8, 2]
- 新建整数数组 C 保存结果,整型变量 t 保存进位,初始 t = 0.
- 将各个位上的数字相加,求出结果对应位上的数字和进位。
- 例如对个位计算: A[0] + B[0] = 7 + 8 = 15, 结果个位上是 5, 进位是 1. 所以 C[0] = 5, 进位 t = 1
- 最后把结果数组 C 中就保存了计算倒序结果,倒序输出就是答案
代码
#include<bits/stdc++.h>
using namespace std;// 定义一个函数add,用于计算两个大整数的和
vector<int> add(vector<int> &A,vector<int> &B)
{// 如果A的长度小于B的长度,交换A和B的位置,保证A的长度大于等于B的长度if(A.size()<B.size()) return add(B,A);vector<int> C; // 定义一个向量C,用于存储结果int t=0; // 定义一个变量t,用于存储进位for(int i=0;i<A.size();i++){t+=A[i]; // 将A的第i个元素加到t中if(i<B.size()) t+=B[i]; // 如果i小于B的长度,将B的第i个元素加到t中C.push_back(t%10); // 将t对10取余的结果添加到C中t/=10; // 更新进位}if(t) C.push_back(t); // 如果最后还有进位,将其添加到C中return C; // 返回结果向量C
}int main()
{string a,b; // 定义两个字符串a和b,用于存储输入的大整数cin>>a>>b; // 从标准输入读取大整数vector<int> A,B; // 定义两个向量A和B,用于存储大整数的每一位数字for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); // 将a的每一位数字添加到A中for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0'); // 将b的每一位数字添加到B中auto C=add(A,B); // 调用add函数计算A和B的和,并将结果存储在向量C中for(int i=C.size()-1;i>=0;i--) cout<<C[i]; // 输出结果向量C的每一位数字return 0;
}
高精度减法
问题描述
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的差。
数据范围
1≤整数长度≤105
输入样例
32
11
输出样例
21
问题分析
首先,定义了一个比较函数cmp,用于比较两个向量的大小。比较规则是先比较长度,如果长度不相等,则返回长度较大的向量;如果长度相等,则从高位到低位逐位比较数字大小,返回较大数字的向量。
然后,定义了一个sub函数,用于计算两个向量的差值,注意处理借位的情况。计算过程中,首先遍历A向量的每一位数字,将其与前一位的进位t相减,得到当前位的结果。如果B的长度小于A,只减去B的前缀部分。接着,将结果加上10取模,防止出现负数。如果结果为负数,则进位t设为1,否则设为0。最后,去掉结果中的前导零。
在main函数中,首先读取两个字符串a和b,然后将它们转换为整数向量A和B。接着,调用cmp函数比较A和B的大小,如果A大于等于B,则计算A-B;否则,计算B-A并输出负号。最后,输出结果向量C。
代码
#include<bits/stdc++.h>
using namespace std;// 比较两个向量的大小,先比较长度,再比较每一位数字的大小
bool cmp(vector<int> &A,vector<int> &B)
{if(A.size()!=B.size()) return A.size()>B.size(); // 如果长度不相等,返回长度较大的向量for(int i=A.size()-1;i>=0;i--){if(A[i]!=B[i]) return A[i]>B[i]; // 如果某一位数字不相等,返回较大数字的向量}return true; // 如果长度和所有位数字都相等,返回true
}// 计算两个向量的差值
vector<int> sub(vector<int> &A,vector<int> &B)
{vector<int> C;for(int i=0,t=0;i<A.size();i++){t=A[i]-t;if(i<B.size()) t-=B[i]; // 如果B的长度小于A,只减去B的前缀部分C.push_back((t+10)%10); // 取模运算,防止出现负数if(t<0) t=1; // 如果t为负数,进位else t=0; // 如果t为正数,不进位}while(C.size()>1 && C.back()==0) C.pop_back(); // 去掉结果中的前导零return C;
}int main()
{string a,b;cin>>a>>b;vector<int> A,B;for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); // 将字符串转换为整数向量for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');vector<int> C;if(cmp(A,B)) C=sub(A,B); // 如果A大于等于B,计算A-Belse C=sub(B,A),cout<<"-"; // 如果A小于B,计算B-A并输出负号for(int i=C.size()-1;i>=0;i--) cout<<C[i]; // 输出结果向量return 0;
}
高精度乘法
问题描述
给定两个非负整数(不含前导 0)A和 B,请你计算 A×B的值。
输入格式
共两行,第一行包含整数 A,第二行包含整数 B。
输出格式
共一行,包含 A×B 的值。
数据范围
1≤A的长度≤100000,0≤B≤10000
输入样例
2
3
输出样例
6
问题分析
该题目主要思路是:遍历A向量的每一位数字,将其与b相乘,然后加上进位t,得到当前位的结果。将结果的个位数添加到C向量中,并将结果除以10,得到新的进位t。
代码
#include<bits/stdc++.h>
using namespace std;// 定义一个函数mul,接收一个整数向量A和一个整数b作为参数,返回一个整数向量C
vector<int> mul(vector<int> &A,int b)
{vector<int> C; // 定义一个空的整数向量Cint t=0; // 定义一个变量t用于存储进位for(int i=0;i<A.size() || t;i++) // 遍历A向量的每一位数字,将其与b相乘,然后加上进位t,得到当前位的结果{if(i<A.size()) t+=A[i]*b; // 如果i小于A的大小,将A[i]乘以b并加到t上C.push_back(t%10); // 将结果的个位数添加到C向量中t/=10; // 将结果除以10,得到新的进位t}while(C.size()>1 && C.back()==0) C.pop_back(); // 去掉C向量中的前导零return C; // 返回整数向量C
}int main()
{string a; // 定义一个字符串aint b; // 定义一个整数bcin>>a>>b; // 从输入流中读取a和b的值vector<int> A; // 定义一个整数向量Afor(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); // 将字符串a转换为整数向量A,从高位到低位存储每一位数字auto C=mul(A,b); // 调用mul函数,计算A和b的乘积,得到整数向量Cfor(int i=C.size()-1;i>=0;i--) cout<<C[i]; // 输出整数向量C的每一位数字,从高位到低位return 0;
}
高精度除法
问题描述
给定两个非负整数(不含前导 0) A,B,请你计算 A/B的商和余数。
输入格式
共两行,第一行包含整数 A,第二行包含整数 B。
输出格式
共两行,第一行输出所求的商,第二行输出所求余数。
数据范围
1≤A的长度≤100000,1≤B≤10000,B 一定不为 0
输入样例
7
2
输出样例
3
1
问题分析
该问题的主要思路是:求得每次除b的余数,并将每次求得的余数乘10,再去除b
代码
#include<bits/stdc++.h>
using namespace std;// 定义一个函数div,用于计算向量A除以整数b的商和余数
vector<int> div(vector<int> &A, int b, int &r) {vector<int> C; // 定义一个空的整数向量Cr = 0; // 初始化余数为0for (int i = A.size() - 1; i >= 0; i--) {r = r * 10 + A[i]; // 将余数乘以10并加上当前位的值C.push_back(r / b); // 将商添加到向量C中r %= b; // 更新余数}reverse(C.begin(), C.end()); // 反转向量C,使其从高位到低位存储while (C.size() > 1 && C.back() == 0) C.pop_back(); // 去掉向量C中的前导零return C; // 返回向量C
}int main() {string a;int b;cin >> a >> b; // 输入字符串a和整数bvector<int> A, C; // 定义两个整数向量A和Cfor (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); // 将字符串a转换为整数向量A,从高位到低位存储每一位数字int r;C = div(A, b, r); // 调用div函数,计算A除以b的商和余数,并将结果存储在向量C中for (int i = C.size() - 1; i >= 0; i--) cout << C[i]; // 输出向量C的每一位数字,从高位到低位cout << endl;cout << r << endl; // 输出余数return 0;
}