高精度加减乘-模板
新版
大数->超过整数型的数,很大的数
小数->int/long long范围的数
加法
#include <bits/stdc++.h> using namespace std; string x, y; vector<int> a, b, c; void add(string x, string y) { int t=0; for (int i=x.size()-1; i>=0; i--) a.push_back(x[i]-'0'); for (int i=y.size()-1; i>=0; i--) b.push_back(y[i]-'0'); for (int i=0; i<a.size() || i<b.size(); i++) { if (i<a.size()) t+=a[i]; if (i<b.size()) t+=b[i]; c.push_back(t%10); t/=10; } if (t) c.push_back(1); } int main() { cin>>x>>y; add(x, y); for (int i=c.size()-1; i>=0; i--) printf("%d", c[i]); return 0; }
减法
#include <bits/stdc++.h> using namespace std; string x, y; vector<int> a, b, c; void sub(string x, string y) { int t=0; for (int i=x.size()-1; i>=0; i--) a.push_back(x[i]-'0'); for (int i=y.size()-1; i>=0; i--) b.push_back(y[i]-'0'); for (int i=0; i<a.size(); i++) { t=a[i]-t; if (i<b.size()) t-=b[i]; c.push_back((t+10)%10); if (t<0) t=1; else t=0; } while (c.size()>1 && c.back()==0) c.pop_back(); } int main() { cin>>x>>y; if (x.size()<y.size() || (x.size()==y.size() && x<y)) { swap(x, y); printf("-"); } sub(x, y); for (int i=c.size()-1; i>=0; i--) printf("%d", c[i]); return 0; }
乘法,大数乘小数
#include <bits/stdc++.h> using namespace std; string x; int b; vector<int> a, c; void mul(string x, int b) { int t=0; for (int i=x.size()-1; i>=0; i--) a.push_back(x[i]-'0'); for (int i=0; i<a.size() || t; i++) { if (i<a.size()) t+=a[i]*b; c.push_back(t%10); t/=10; } } int main() { cin>>x>>b; if (b==0) { printf(0); return 0; } mul(x, b); for (int i=c.size()-1; i>=0; i--) printf("%d", c[i]); return 0; }
乘法,大数乘大数
#include <bits/stdc++.h> using namespace std; string x, y; vector<int> a, b, c(100010); void mul(string x, string y) { int t=0; for (int i=x.size()-1; i>=0; i--) a.push_back(x[i]-'0'); for (int i=y.size()-1; i>=0; i--) b.push_back(y[i]-'0'); for (int i=0; i<a.size(); i++) for (int j=0; j<b.size(); j++) { c[i+j]+=a[i]*b[j]; //根据规律得来,观察上图可发现,C的下标是a的下标i+a的下标j,注意此处下标从0开始,图中下标从1开始,自己带入即可发现规律了 c[i+j+1]+=c[i+j]/10; c[i+j]%=10; } while (c.size()>1 && c.back()==0) c.pop_back(); } int main() { cin>>x>>y; mul(x, y); for (int i=c.size()-1; i>=0; i--) printf("%d", c[i]); return 0; }
除法,大数除以小数,洛谷的题开longlong才能过!!
#include <bits/stdc++.h> using namespace std; string x; int b; vector<int> a, c; void div(string x, int b, int &r) { r=0; for (int i=x.size()-1; i>=0; i--) a.push_back(x[i]-'0'); //正常情况顺着遍历即可,为了满足一些题目加减乘除混合,所以改变大数存储方式 for (int i=a.size()-1; i>=0; i--) { r=r*10+a[i]; c.push_back(r/b); r%=b; } reverse(c.begin(), c.end()); while (c.size()>1 && c.back()==0) c.pop_back(); } int main() { cin>>x>>b; if (b==0) { printf(0); return 0; } int r=0; div(x, b, r); for (int i=c.size()-1; i>=0; i--) printf("%d", c[i]); //printf("\n%d", r); 余数 return 0; }
旧版
例题(一本通): 乘法 http://ybt.ssoier.cn:8088/problem_show.php?pid=1307
#include <bits/stdc++.h> using namespace std; struct bignum { int len, s[1010]; }a, b; string num1, num2; void print(bignum x) { //cout<<'('<<x.len<<')'; int flag=0; for (int i=x.len-1; i>=0; i--) { if (x.s[i]!=0) flag=1; if (flag==1) cout<<x.s[i]; } cout<<endl; } bignum cheng(bignum a, bignum b) { bignum c; c.len=a.len+b.len; memset(c.s, 0, sizeof c.s); for (int i=0; i<b.len; i++) for (int j=0; j<a.len; j++) c.s[i+j]+=b.s[i]*a.s[j]; for (int i=0; i<c.len; i++) if (c.s[i]>=10) { c.s[i+1]+=c.s[i]/10; c.s[i]%=10; } return c; } int main() { cin>>num1>>num2; if (num1.size()<num2.size() || (num1.size()==num2.size() && num1<num2)) swap(num1, num2); a.len=num1.size(), b.len=num2.size(); for (int i=0; i<num1.size(); i++) a.s[a.len-i-1]=num1[i]-'0'; for (int i=0; i<num2.size(); i++) b.s[b.len-i-1]=num2[i]-'0'; a=cheng(a, b); print(a); return 0; }
http://ybt.ssoier.cn:8088/problem_show.php?pid=1174 (和前面一样的做法)
加法 http://ybt.ssoier.cn:8088/problem_show.php?pid=1168
#include <bits/stdc++.h> using namespace std; struct bignum { int len, s[1010]; }a, b; string num1, num2; void print(bignum x) { //cout<<'('<<x.len<<')'; int flag=0; for (int i=x.len-1; i>=0; i--) { if (x.s[i]!=0) flag=1; if (flag==1) cout<<x.s[i]; } cout<<endl; } bignum jia(bignum a, bignum b) { bignum c; int len=0; if (a.len<b.len) swap(a, b); c.len=a.len, len=a.len; memset(c.s, 0, sizeof c.s); for (int i=0; i<len; i++) c.s[i]=a.s[i]+b.s[i]; for (int i=0; i<len; i++) if (c.s[i]>=10) { c.s[i+1]++; c.s[i]-=10; if (i==len-1) c.len++; } return c; } int main() { cin>>num1>>num2; if (num1.size()<num2.size() || (num1.size()==num2.size() && num1<num2)) swap(num1, num2); a.len=num1.size(), b.len=num2.size(); for (int i=0; i<num1.size(); i++) a.s[a.len-i-1]=num1[i]-'0'; for (int i=0; i<num2.size(); i++) b.s[b.len-i-1]=num2[i]-'0'; a=jia(a, b); print(a); return 0; }
减法 http://ybt.ssoier.cn:8088/problem_show.php?pid=1169
#include <bits/stdc++.h> using namespace std; struct bignum { int len, s[1010]; }a, b; string num1, num2; void print(bignum x) { //cout<<'('<<x.len<<')'; int flag=0; for (int i=x.len-1; i>=0; i--) { if (x.s[i]!=0) flag=1; if (flag==1) cout<<x.s[i]; } cout<<endl; } bignum jian(bignum a, bignum b) { bignum c; int len=0; if (a.len<b.len) swap(a, b); c.len=a.len, len=a.len; memset(c.s, 0, sizeof c.s); for (int i=0; i<len; i++) c.s[i]=a.s[i]-b.s[i]; for (int i=0; i<len; i++) if (c.s[i]<0) { c.s[i+1]--; c.s[i]+=10; if (i==len-1) c.len++; } return c; } int main() { cin>>num1>>num2; if (num1.size()<num2.size() || (num1.size()==num2.size() && num1<num2)) swap(num1, num2); a.len=num1.size(), b.len=num2.size(); for (int i=0; i<num1.size(); i++) a.s[a.len-i-1]=num1[i]-'0'; for (int i=0; i<num2.size(); i++) b.s[b.len-i-1]=num2[i]-'0'; a=jian(a, b); print(a); return 0; }
扩展 1170:计算2的N次方 http://ybt.ssoier.cn:8088/problem_show.php?pid=1170
#include <bits/stdc++.h> using namespace std; struct bignum { int len, s[1010]; }a, b; int n; void print(bignum x) { //cout<<'('<<x.len<<')'; int flag=0; for (int i=x.len-1; i>=0; i--) { if (x.s[i]!=0) flag=1; if (flag==1) cout<<x.s[i]; } cout<<endl; } bignum cheng(bignum a, bignum b) { bignum c; c.len=a.len+b.len; memset(c.s, 0, sizeof c.s); for (int i=0; i<b.len; i++) for (int j=0; j<a.len; j++) c.s[i+j]+=b.s[i]*a.s[j]; for (int i=0; i<c.len; i++) if (c.s[i]>=10) { c.s[i+1]+=c.s[i]/10; c.s[i]%=10; } return c; } int main() { cin>>n; b.s[0]=2, b.len=1; a.s[0]=1, a.len=1; for (int i=1; i<=n; i++) a=cheng(a, b); print(a); return 0; }
1173:阶乘和(卡了最久) http://ybt.ssoier.cn:8088/problem_show.php?pid=1173 和洛谷的阶乘和一样 https://www.luogu.com.cn/problem/P1009
代码:
#include <bits/stdc++.h> using namespace std; struct bignum { int len, s[1010]; }a, t, x; int n; void print(bignum x) { //cout<<'('<<x.len<<')'; int flag=0; for (int i=x.len-1; i>=0; i--) { if (x.s[i]!=0) flag=1; if (flag==1) cout<<x.s[i]; } cout<<endl; } bignum jia(bignum a, bignum b) { bignum c; int len=0; if (a.len<b.len) swap(a, b); c.len=a.len, len=a.len; memset(c.s, 0, sizeof c.s); for (int i=len-1; i>=0; i--) c.s[i]=a.s[i]+b.s[i]; for (int i=0; i<len; i++) if (c.s[i]>=10) { c.s[i+1]++; c.s[i]-=10; if (i==len-1) c.len++; } return c; } bignum cheng(bignum a, bignum b) { bignum c; c.len=a.len+b.len; memset(c.s, 0, sizeof c.s); for (int i=b.len-1; i>=0; i--) for (int j=a.len-1; j>=0; j--) c.s[i+j]+=b.s[i]*a.s[j]; for (int i=0; i<c.len; i++) if (c.s[i]>=10) { c.s[i+1]+=c.s[i]/10; c.s[i]%=10; } return c; } int main() { cin>>n; for (int i=1; i<=n; i++) { memset(t.s, 0, sizeof t.s); t.s[0]=1, t.len=1; for (int j=1; j<=i; j++) { memset(x.s, 0, sizeof x.s); if (j>=1 && j<=9) x.len=1, x.s[0]=j; else if (j>=10 && j<=99) x.len=2, x.s[1]=j/10%10, x.s[0]=j%10; else x.len=3, x.s[2]=j/100%10, x.s[1]=j/10%10, x.s[0]=j%10; t=cheng(t, x); } a=jia(a, t); } print(a); return 0; }