AcWing 791. 高精度加法(高精度+高精度)
给定两个正整数,计算它们的和。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的和。
数据范围
1≤整数长度≤100000
输入样例:
12
23
输出样例:
35
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
#define pb push_back
#define pp pop_back
vi add(vi &a, vi &b)
{
vi sum; int t = 0;
for(int i=0; i<a.size()||i<b.size()||t; ++i)
{
if(i<a.size()) t+=a[i];
if(i<b.size()) t+=b[i];
sum.pb(t%10);
t/=10;
}
return sum;
}
int main()
{
string a, b; vi aa, bb;
cin>>a>>b;
for(int i=a.size()-1, j=b.size()-1; i>=0||j>=0; --i, --j)
{
if(i>=0) aa.pb(a[i]-'0');
if(j>=0) bb.pb(b[j]-'0');
}
vi c = add(aa, bb);
for(int i=c.size()-1; i>=0; --i) printf("%d", c[i]);
return 0;
}
AcWing 792. 高精度减法(高精度-高精度)
给定两个正整数,计算它们的差,计算结果可能为负数。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的差。
数据范围
1≤整数长度≤10^5
输入样例:
32
11
输出样例:
21
#include<iostream>
#include<string>
#include<vector>
using namespace std;
bool judge(vector<int> &a,vector<int> &b)//一定要判断是否有A>=B(满足返回true,否则返回false)
{
if(a.size()>b.size()) return true;
else if(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;
}
else return false;
}
vector<int> sub(vector<int>& a,vector<int>& b)
{
vector<int> res;//差
int t=0;//存储借位
for(int i=0;i<=a.size()-1;i++)
{
t=a[i]-t;
if(i<b.size()) t-=b[i];
res.push_back((t+10)%10);//如果t>=0,则将t压入,如果t<0,则将t+10压入,这里是将两种情况合并了
if(t<0) t=1;//如不够减,向上级借位1
else t=0;//够减则无需借位
}
while(res.size()>1&&!res.back()) res.pop_back();//去除前导0
return res;
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
string a,b;
vector<int> A,B;
cin>>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');
if(judge(A,B))//如果A>=B,计算A-B
{
vector<int> c=sub(A,B);
for(int i=c.size()-1;i>=0;i--) cout<<c[i];
cout<<endl;
}
else//如A<B,则计算B-A,最后应当添加一个负号
{
cout<<'-';
vector<int> c=sub(B,A);
for(int i=c.size()-1;i>=0;i--) cout<<c[i];
cout<<endl;
}
return 0;
}
AcWing 793. 高精度乘法1(高精度×低精度)
给定两个整数 A 和 B,请你计算 A×B 的值。
输入格式
共两行,第一行包含整数 A,第二行包含整数 B。
输出格式
共一行,包含 A×B 的值。
数据范围
1≤A的长度≤100000,
0≤B≤10000
输入样例:
2
3
输出样例:
6
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
#define pb push_back
#define pp pop_back
vi mul(vi &a, int b)
{
int t = 0; vi res;
for(int i=0;i<a.size()||t; ++i)
{
if(i<a.size()) t+=a[i]*b;
res.pb(t%10);
t/=10;
}while(res.size()>1&&!res.back()) res.pp();
return res;
}
int main()
{
string a; int b;
cin>>a>>b;
vi aa;
for(int i=a.size()-1; i>=0; --i) aa.pb(a[i]-'0');
vi c = mul(aa, b);
for(int i=c.size()-1; i>=0; --i) printf("%d", c[i]);
puts("");
return 0;
}
附:高精度乘法2(高精度×高精度)
(转自 白马金羁侠少年)
#include <iostream>
#include <vector>
using namespace std;
vector<int> mul(vector<int> &A, vector<int> &B) {
vector<int> C(A.size() + B.size(), 0); // 初始化为 0,且999*99最多 5 位
for (int i = 0; i < A.size(); i++)
for (int j = 0; j < B.size(); j++)
C[i + j] += A[i] * B[j];
int t = 0;
for (int i = 0; i < C.size(); i++) { // i = C.size() - 1时 t 一定小于 10
t += C[i];
C[i] = t % 10;
t /= 10;
}
while (C.size() > 1 && C.back() == 0) C.pop_back(); // 必须要去前导 0,因为最高位很可能是 0
return C;
}
int main() {
string a, b;
cin >> a >> b; // a = "1222323", b = "2323423423"
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');
auto C = mul(A, B);
for (int i = C.size() - 1; i >= 0; i--)
cout << C[i];
return 0;
}
AcWing 794. 高精度除法(高精度÷低精度)
给定两个非负整数 A,B,请你计算 A/B 的商和余数。
输入格式
共两行,第一行包含整数 A,第二行包含整数 B。
输出格式
共两行,第一行输出所求的商,第二行输出所求余数。
数据范围
1≤A的长度≤100000,
1≤B≤10000,
B 一定不为 0
输入样例:
7
2
输出样例:
3
1
#include<iostream>
#include<string>
#include<algorithm>
#include <vector>
using namespace std;
vector<int> div(vector<int> &a,int b,int &r)
{
vector<int> ans;//商
r=0;//余数
for(int i=a.size()-1;i>=0;i--)//与之前三个不一样,这里是从A的最高位开始模拟运算
{
r=r*10+a[i];
ans.push_back(r/b);//高位到低位依次压入ans
r%=b;
}
reverse(ans.begin(),ans.end());/*由于ans内的数是从高位存储到低位,但主函数中输出答案是要逆向输出,
所以在这里要将ans反转一下,改为从低位存到高位,这样在主函数中才能正确输出*/
while(ans.size()>1&&ans.back()==0) ans.pop_back();//去除前导0
return ans;
}
int main()
{
string a;
vector<int> A;
int r,b;
cin>>a>>b;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
auto res=div(A,b,r);
for(int i=res.size()-1;i>=0;i--)//倒序输出结果
cout<<res[i];
cout<<endl<<r<<endl;
return 0;
}