zoukankan      html  css  js  c++  java
  • 高精度板子

    前言:写一写自己高精度易错的地方,内容并不适合初学者,还有高精除高精的锅蒟蒻补不上了.


    I.高精加法

    记住进位数x的定义,并记得最后x!=0时将x加上.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define R register
    char s[510],t[510];
    int x,id,lena,lenb,a[510],b[510],c[510];
    int main()
    {
    //    freopen("s.in","r",stdin);
    //    freopen("s.out","w",stdout);
        scanf("%s",s),scanf("%s",t);
        lena=strlen(s),lenb=strlen(t);
        for(R int i=0;i<lena;++i)
            a[i]=s[lena-i-1]-'0';
        for(R int j=0;j<lenb;++j)
            b[j]=t[lenb-j-1]-'0';
        while(id<lena||id<lenb)
        {    
            c[id]=a[id]+b[id]+x;
            x=c[id]/10;
            c[id]%=10;
            ++id;
        }
        --id;
        if(x!=0)
            c[++id]=x;
        for(R int j=id;j>=0;--j)
            printf("%d",c[j]);
        return 0;
    }

    II.高精减法

    ①理解借位x的定义,每次做减法时要考虑是否要借位,并在这之后将x变为1或0.

    ②注意被减数比减数大的情况,要在运算之前将次交换.

    ③清前导零时,要特判"0-0"的特殊情况.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define e exit(0)
    #define R register
    char a[10010],b[10010];
    int x,id,lena,lenb,lens,lent,s[10010],t[10010],c[10010];
    bool check()
    {
        if(lena<lenb)
            return true;
        else if(lena>lenb)
            return false;
        else if(lena==lenb)
        {    
            for(R int i=0;i<lena;++i)
                if(a[i]<b[i])
                    return true;
            return false;
        }
    }
    void chang()
    {
        printf("-");
        char c[10010];
        for(R int i=0;i<lena;++i)
            c[i]=a[i];
        for(R int i=0;i<lenb;++i)
            a[i]=b[i];
        for(R int i=0;i<lena;++i)
            b[i]=c[i];
        swap(lena,lenb);
    }
    int main()
    {
    //    freopen("s.in","r",stdin);
    //    freopen("s.out","w",stdout);
        scanf("%s",a),scanf("%s",b);
        lena=strlen(a),lenb=strlen(b);
        if(check()) chang();
        lens=lena,lent=lenb;
        for(R int i=0;i<lens;++i)
            s[i]=a[lena-i-1]-'0';
        for(R int i=0;i<lent;++i)
            t[i]=b[lenb-i-1]-'0';
        while(id<lena||id<lenb){
            if(s[id]-t[id]-x<0){
                c[id]=s[id]+10-t[id]-x;
                x=1;
            }
            else if(s[id]-t[id]-x>=0){
                c[id]=s[id]-t[id]-x;
                x=0;
            }
            ++id;
        }
        --id;
        while(c[id]==0&&id>=0)
            --id;
        if(id==-1)
        {
            cout<<0;
            return 0;
        }
        for(R int i=id;i>=0;--i)
            cout<<c[i];
        return 0;
    }

    III.高精乘

    ①建议字符串的id从1开始.

    ②特判" 0*0 "的情况.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define R register
    char s[2010],t[2010];
    int a[2010],b[2010],c[5010],lena,lenb,lenc,x;
    int main()
    {
    //    freopen("s.in","r",stdin);
    //    freopen("s.out","w",stdout);
        scanf("%s",s+1),scanf("%s",t+1);
        lena=strlen(s+1),lenb=strlen(t+1);
        if((lena==1&&s[1]=='0')||(lenb==1&&t[1]=='0'))
        {
            printf("0");
            return 0;
        }
        for(R int i=1;i<=lena;++i)
            a[i]=s[lena-i+1]-'0';
        for(R int i=1;i<=lenb;++i)
            b[i]=t[lenb-i+1]-'0';
        for(R int i=1;i<=lena;++i)
        {
            x=0;
            for(R int j=1;j<=lenb;++j)
            {
                c[i+j-1]=a[i]*b[j]+c[i+j-1]+x;
                x=c[i+j-1]/10;
                c[i+j-1]%=10;
            }
            c[lenb+i]=x;
        }
        lenc=lena+lenb;
        while(c[lenc]==0)
            --lenc;
        for(R int i=lenc;i>=1;--i)
            printf("%d",c[i]);
        return 0;
    }

    IV.高精除低精

    够除就除,不够除就存,注意前导0.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define R register
    #define ll long long
    char s[5010];
    long long a[5010],c[5010],lena,last,deep,b,sur;
    int main()
    {
    //    freopen("s.in","r",stdin);
    //    freopen("s.out","w",stdout);
        scanf("%s",s+1),scanf("%lld",&b);
        lena=strlen(s+1);
        for(R ll i=1;i<=lena;++i)
            a[i]=s[i]-'0';
        for(R ll i=1;i<=lena;++i){
            last=last*10+a[i];
            if(last<b&&sur==1){c[++deep]=0;}
            else if(last>=b){
                c[++deep]=last/b;
                last%=b;
                sur=1;
            }
        }
        for(R int i=1;i<=deep;++i)
            printf("%lld",c[i]);
        return 0;
    }
  • 相关阅读:
    #1071 : 小玩具
    #1063 : 缩地
    #1124 : 好矩阵
    hiho#1145 : 幻想乡的日常
    hiho#14
    hiho 毁灭者问题
    西南民大oj(递推)
    西南民大oj(矩阵快速幂)
    西南民大oj(两园交求面积)
    hdu2844(多重背包)
  • 原文地址:https://www.cnblogs.com/xqysckt/p/11253857.html
Copyright © 2011-2022 走看看