【テンプレート】高精

首先贴出高精板子——感觉超好看!

//参考自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; 
}
View Code

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;
}
View Code

 

posted @ 2017-11-06 15:59  夜雨声不烦  阅读(185)  评论(0编辑  收藏  举报