首先贴出高精板子——感觉超好看!
//参考自Candy? #include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; const int Mod = 10; struct Big { int a[520],n; int& operator [](int x) {return a[x];} Big() : n(0) {memset(a,0,sizeof(a));} void ini(int x) {a[++n]=x;} }; Big operator * (Big a,Big b) { Big c; for(int i=1; i<=a.n; i++) { int q=0; for(int j=1; j<=b.n; j++) q+=c[i+j-1]+a[i]*b[j],c[i+j-1]=q%Mod,q/=Mod; c[i+b.n]=q; } c.n=a.n+b.n; while(c.n>1 && c[c.n]==0) c.n--; return c; } Big operator * (Big a,int b) { int q=0; for(int i=1; i<=a.n; i++) q+=a[i]*b,a[i]=q%Mod,q/=Mod; while(q) a[++a.n]=q%10,q/=10; return a; } Big operator + (Big a,Big b) { int q=0,n=max(a.n,b.n); for(int i=1; i<=n; i++) { q+= i<=a.n ? a[i] : 0; q+= i<=b.n ? b[i] : 0; a[i]=q%Mod,q/=Mod; } a.n=n; if(q) a[++a.n]=q; return a; } Big operator - (Big a,Big b) { for(int i=1; i<=b.n; i++) { if(a[i]<b[i]) a[i]+=Mod,a[i+1]--; a[i]-=b[i]; } int q=b.n+1; while(a[q]<0) a[q]+=Mod,a[++q]--; while(a.n>1 && a[a.n]==0) a.n--; return a; } void Print(Big &a) { for(int i=a.n; i>=1; i--) printf("%d",a[i]); } string s1,s2; int main() { cin>>s1>>s2; int len1=s1.length(),len2=s2.length(); Big a,b,c; for(int i=len1-1; i>=0; i--) a.ini(s1[i]-'0'); for(int i=len2-1; i>=0; i--) b.ini(s2[i]-'0'); //c=...; c=a+b; Print(c); return 0; }
练手题:
1.luogu P1018 乘积最大
思路:
dp+高精
坑点:
我不会写高精+单精,所以有的地方把单精改为了高精
code:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #define INF 0x7fffffff using namespace std; const int M = 100; int n,k; struct Big { int a[50],n; int& operator [](int x) {return a[x];} Big() : n(1) {memset(a,0,sizeof(a));} void ini(int x) {a[1]=x; n=1;} }p,z,dp[M/10][M],sum[M][M]; Big operator * (Big a,Big b) { Big c; for(int i=1; i<=a.n; i++) { int q=0; for(int j=1; j<=b.n; j++) q+=c[i+j-1]+a[i]*b[j],c[i+j-1]=q%10,q/=10; c[i+b.n]=q; } c.n=a.n+b.n; while(c.n>1 && c[c.n]==0) c.n--; return c; } Big operator * (Big a,int b) { int q=0; for(int i=1; i<=a.n; i++) q+=a[i]*b,a[i]=q%10,q/=10; while(q) a[++a.n]=q%10,q/=10; return a; } Big operator + (Big a,Big b) { int q=0,n=max(a.n,b.n); for(int i=1; i<=n; i++) { q+= i<=a.n ? a[i] : 0; q+= i<=b.n ? b[i] : 0; a[i]=q%10,q/=10; } a.n=n; if(q) a[++a.n]=q; return a; } Big cmp(Big a,Big b) { //等价于取max int an=a.n,bn=b.n; if(an<bn) return b; if(an>bn) return a; for(int i=an; i>=1; i--) { if(a[i]>b[i]) return a; if(a[i]<b[i]) return b; } return a; } int main() { scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) scanf("%1d",&p[i]); for(int i=1; i<=n; i++) for(int j=i; j<=n; j++) { int g=p[j]; z.ini(g); //单精——>高精 sum[i][j]=sum[i][j-1]*10+z; } for(int i=1; i<=n; i++) dp[i][0]=sum[1][i]; for(int now=1; now<=k; now++) for(int i=now+1; i<=n; i++) for(int j=1; j<i; j++) dp[i][now]=cmp(dp[i][now],dp[j][now-1]*sum[j+1][i]); for(int i=dp[n][k].n; i>=1; i--) printf("%d",dp[n][k].a[i]); return 0; }
2.luogu P1009 阶乘之和
code:
#include <iostream> #include <cstdio> #include <cstring> #define LL long long using namespace std; struct Big { int a[120],n; int& operator [](int x) {return a[x];} Big() : n(1){memset(a,0,sizeof(a));} void ini(int x) {a[1]=x; n=1;} }; Big operator + (Big a,Big b) { int q=0,n=max(a.n,b.n); for(int i=1; i<=n; i++) { q+= i<=a.n ? a[i] : 0; q+= i<=b.n ? b[i] : 0; a[i]=q%10,q/=10; } a.n=n; if(q) a[++a.n]=q; return a; } Big operator * (Big a,int b) { int q=0; for(int i=1; i<=a.n; i++) q+=a[i]*b,a[i]=q%10,q/=10; while(q) a[++a.n]=q%10,q/=10; return a; } int n; int main() { scanf("%d",&n); Big sum,last; sum.ini(0);last.ini(1); for(int i=1; i<=n; i++) { last=last*i; sum=sum+last; } for(int i=sum.n; i>=1; i--) printf("%d",sum.a[i]); return 0; }