1、高精度加法
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的和。
数据范围
1≤整数长度≤100000
#include<bits/stdc++.h>
using namespace std;
int main(){
string sa, sb;
cin >> sa >> sb;
vector<int> A, B, C;
//逆序压入容器,因为逆序好处理进制位
//sa[i] - '0' 的作用是将每个字符转换成数字
for(int i = sa.length() - 1; i >= 0; i--) A.push_back(sa[i] - '0');
for(int i = sb.length() - 1; i >= 0; i--) B.push_back(sb[i] - '0');
int t = 0;
for(int i = 0; i < max(sa.length(), sb.length()); i++){
if(i < sa.length()) t += A[i];
if(i < sb.length()) t += B[i];
C.push_back(t % 10); //保留个位并将其压入C容器
t /= 10; //若t超过10,则向前进1
}
if(t){ //若输入完所有数字后,t不等于零
C.push_back(1); //则在末尾添上1
}
for(int i = C.size() - 1; i >= 0; i--){
cout << C[i]; //容器输入时是逆序的,所以输出时也要逆过来
}
return 0;
}
2、高精度减法
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的差。
数据范围
1≤整数长度≤105
#include<bits/stdc++.h>
using namespace std;
vector<int> A, B, C;
bool cmp (vector<int> &A, vector<int> &B){ //用来比较A,B的大小
if(A.size() != B.size()){ //若A和B的位数不同
return A.size() > B.size(); //则可以直接比较,位数多的数大
}else{ //若A和B的位数相同
for(int i = A.size() - 1; i >= 0; i--){ //比大小,需将逆序输入的数再次逆序
//然后从最高位开始往后,分别对两个数的每一位进行比较大小
if(A[i] != B[i]){ //如果某位上的数字A和B的不相等
return A[i] > B[i]; //就可以直接比较A和B在那一位上的数的大小,
}
}
}
return true;
}
vector<int> sub(vector<int> &A, vector<int> &B){ //计算减法的方法
int t = 0; //借位
for(int i = 0; i < A.size(); i++){
t = (A[i] - t); //如果有借位,则在减法刚开始时先减去借位数t
if(i < B.size()){ //如果B还有位数没有减的话
t = t - B[i];
}
C.push_back((t + 10) % 10);
//(t+10)%10作为某一位上相减的结果,+10为了防止出现负数
if(t < 0){ //某一位上不够减
t = 1; //向后面借1
}else{
t = 0;
}
}
while(C.size() > 1 && C.back() == 0){ //while循环去掉前导零
//C.size() > 1,说明如果结果就一位数字,就不用去除前导零
//C.back() == 0,说明容器最后一个的位数是零的话
C.pop_back(); //去掉容器的最后一个位数
}
return C;
}
int main(){
string sa, sb;
cin >> sa >> sb;
//逆序输入容器 ,因为逆序好处理进制
for(int i = sa.length() - 1; i >= 0; i--) A.push_back(sa[i] - '0');
for(int i = sb.length() - 1; i >= 0; i--) B.push_back(sb[i] - '0');
if(cmp(A, B)){ //比大小,若A大于B
sub(A, B); //说明是大数减去小数,A直接减B
for(int i = C.size() - 1; i >= 0; i--){ //逆序输入,所以逆序输出
cout << C[i];
}
}else{ //A小于B
cout << "-"; //说明是小数减去大数,要在前面添加负号
sub(B , A); //用大数B减小数A后在前面加负号即可
for(int i = C.size() - 1; i >= 0; i--){ //逆序输出
cout << C[i];
}
}
return 0;
}
3、高精度乘法
给定两个非负整数(不含前导 0) A 和 B,请你计算 A×B 的值。
输入格式
共两行,第一行包含整数 A,第二行包含整数 B。
输出格式
共一行,包含 A×B 的值。
数据范围
1≤A的长度≤100000
0≤B≤10000
#include<bits/stdc++.h>
using namespace std;
int main(){
string sa;
int b;
cin >> sa >> b;
vector<int> A, C;
//和上面不同,这里b是int型,故不用压入容器
for(int i = sa.length() - 1; i >= 0; i--) A.push_back(sa[i] - '0');
int t = 0;
for(int i = 0; i < A.size(); i++){
t += A[i] * b; //每一位上进行乘法,并加上进位数t
C.push_back(t % 10); //保留乘出结果的个位数到对应位上
t /= 10; //算出进位数t
}
if(t){ //如果还有进位数
C.push_back(t); //将其添入容器最后一位
}
while (C.size() > 1 && C.back() == 0) C.pop_back(); //去掉前导零
for(int i = C.size() - 1; i >= 0; i--){ //逆序输出
cout << C[i];
}
return 0;
}
4、高精度除法
给定两个非负整数(不含前导 0) A,B请你计算 A/B 的商和余数。
输入格式
共两行,第一行包含整数 A,第二行包含整数 B。
输出格式
共两行,第一行输出所求的商,第二行输出所求余数。
数据范围
1≤A的长度≤100000
1≤B≤10000
B 一定不为 0
#include<bits/stdc++.h>
using namespace std;
vector<int> A, C;
int main(){
string sa;
int b;
cin >> sa >> b;
//根据除法运算规律(我们手算的时候就是从最高位开始算),不必逆序压入容器
for(int i = 0; i < sa.length(); i++) A.push_back(sa[i] - '0');
int t = 0; //t是余数
for(int i = 0; i < A.size(); i++){
t = t * 10 + A[i]; //t为零,说明可以整除
//t不为零,说明前一位除后结果有余数
//故在这一位先让前一位的余数乘10再加上这位上的数
C.push_back(t / b); //保留相除后结果的个位数到对应位上
t %= b; //求出余数t
}
reverse(C.begin(), C.end()); //逆序,是为了方便去除前导零
//不逆序的话,从前往后去除前导零不方便
//其一是因为vector没有如pop_back类似的方法去去除第一个位置的元素
// 其二是因为先去除前面的数,那后面的数也要相应地整体往前移动,过于复杂
while(C.size() > 1 && C.back() == 0){ //去除前导零
C.pop_back();
}
for(int i = C.size() - 1; i >= 0; i--){ //前面逆序了,故这里逆序输出
cout << C[i];
}
puts(""); //换行
cout << t;
return 0;
}