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

    加法  只限两个非负整数相加

    string add(string a,string b) {
        string ans;
        memset(ta,0,sizeof(ta));
        memset(tb,0,sizeof(tb));
        int lena=a.size(),lenb=b.size();
        for(int i=0;i<lena;i++) ta[lena-i-1]=a[i]-'0';
        for(int i=0;i<lenb;i++) tb[lenb-i-1]=b[i]-'0';
        int len=max(lena,lenb);
        for(int i=0;i<len;i++) {
            ta[i]+=tb[i];
            ta[i+1]+=ta[i]/10,ta[i]%=10;
        }
        if(ta[len]) len++;
        for(int i=len-1;i>=0;i--) ans+=ta[i]+'0';
        return ans;
    }
    View Code

    减法 只限大的非负整数减小的非负整数

    string sub(string a,string b) {
        string ans;
        memset(ta,0,sizeof(ta));
        memset(tb,0,sizeof(tb));
        int la=a.size(),lb=b.size();
        for(int i=0;i<la;i++) ta[la-1-i]=a[i]-'0';
        for(int i=0;i<lb;i++) tb[lb-1-i]=b[i]-'0';
        int len=max(lena,lenb);
        for(int i=0;i<len;i++) {
            ta[i]-=tb[i];
            if(ta[i]<0) ta[i]+=10,ta[i+1]--;
        }
        while(!ta[--len]&&len>0); len++;
        for(int i=len-1;i>=0;i--) ans+=ta[i]+'0';
        return ans;
    }
    View Code

    乘法 

    高精度乘高精度

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <map>
    #include <queue>
    #include <set>
    #include <vector>
    using namespace std;
    #define L(x) (1 << (x))
    const double PI=acos(-1.0);
    const int Maxn=133015;
    double ax[Maxn],ay[Maxn], bx[Maxn], by[Maxn];
    char sa[Maxn/2],sb[Maxn/2];
    int sum[Maxn];
    int x1[Maxn],x2[Maxn];
    int revv(int x,int bits) {
        int ret=0;
        for(int i=0;i<bits;i++) {
            ret<<=1; ret|=x&1; x>>=1;
        }
        return ret;
    }
    void fft(double * a,double * b,int n,bool rev) {
        int bits=0;
        while(1<<bits<n) ++bits;
        for(int i=0;i<n;i++) {
            int j=revv(i,bits);
            if(i<j) swap(a[i],a[j]),swap(b[i],b[j]);
        }
        for (int len=2;len<=n;len<<=1) {
            int half=len>>1;
            double wmx=cos(2*PI/len),wmy=sin(2*PI/len);
            if(rev) wmy=-wmy;
            for (int i=0;i<n;i+=len) {
                double wx=1,wy=0;
                for(int j=0;j<half;j++) {
                    double cx=a[i+j],cy=b[i+j];
                    double dx=a[i+j+half],dy=b[i+j+half];
                    double ex=dx*wx-dy*wy,ey=dx*wy+dy*wx;
                    a[i+j]=cx+ex,b[i+j]=cy+ey;
                    a[i+j+half]=cx-ex,b[i+j+half]=cy-ey;
                    double wnx=wx*wmx-wy*wmy,wny=wx*wmy+wy*wmx;
                    wx=wnx,wy=wny;
                }
            }
        }
        if (rev) 
            for(int i=0;i<n;i++) a[i]/=n,b[i]/=n;
    }
    int solve(int a[],int na,int b[],int nb,int ans[]) {
        int len=max(na,nb),ln;
        for(ln=0;L(ln)<len;++ln);
        len=L(++ln);
        for(int i=0;i<len;i++) {
            if(i>=na) ax[i]=0,ay[i]=0;
            else ax[i]=a[i],ay[i]=0;
        }
        fft(ax, ay, len, 0);
        for(int i=0;i<len;i++) {
            if(i>=nb) bx[i]=0,by[i]=0;
            else bx[i]=b[i],by[i]=0;
        }
        fft(bx,by,len,0);
        for(int i=0;i<len;i++) {
            double cx=ax[i]*bx[i]-ay[i]*by[i];
            double cy=ax[i]*by[i]+ay[i]*bx[i];
            ax[i]=cx,ay[i]=cy;
        }
        fft(ax,ay,len,1);
        for(int i=0;i<len;i++) ans[i]=(int)(ax[i]+0.5);
        return len;
    }
    string mul(string sa,string sb) {
        int l1,l2,l,i;
        string ans;
        memset(sum,0,sizeof(sum));
        l1=sa.size(),l2=sb.size();
        for(i=0;i<l1;i++) x1[i]=sa[l1-i-1]-'0';
        for(i=0;i<l2;i++) x2[i]=sb[l2-i-1]-'0';
        l=solve(x1,l1,x2,l2,sum);
        for(i=0;i<l||sum[i]>=10;i++) {
            sum[i+1]+=sum[i]/10;
            sum[i]%=10;
        }
        l=i;
        while(sum[l]<=0&&l>0) l--;
        for(i=l;i>=0;i--) ans+=sum[i]+'0';
        return ans;
    }
    int main() {
        string a,b;
        while(cin>>a>>b) cout<<mul(a,b)<<endl;
        return 0;
    }
    View Code

    高精度乘单精度

    string mul(string a,int b) {
        memset(ta,0,sizeof(ta));
        string ans;
        int lena=a.size();
        fill(ta,ta+maxn,0);
        for(int i=lena-1;i>=0;i--) ta[lena-i-1]=a[i]-'0';
        int w=0;
        for(int i=0;i<lena;i++) ta[i]=ta[i]*b+w,w=ta[i]/10,ta[i]=ta[i]%10;
        while(w) ta[lena++]=w%10,w/=10;
        lena--;
        while(lena>=0) ans+=ta[lena--]+'0';
        return ans;
    }
    View Code

    除法

    高精度除高精度

    int sub(int *a,int *b,int La,int Lb) {
        if(La<Lb) return -1;
        if(La==Lb) {
            for(int i=La-1;i>=0;i--)
                if(a[i]>b[i]) break;
                else if(a[i]<b[i]) return -1;
     
        }
        for(int i=0;i<La;i++) {
            a[i]-=b[i];
            if(a[i]<0) a[i]+=10,a[i+1]--;
        }
        for(int i=La-1;i>=0;i--)
            if(a[i]) return i+1;
        return 0;
    }
    string div(string n1,string n2,int nn) {
    //n1,n2是字符串表示的被除数,除数,nn是选择返回商还是余数
         const int L=1e5;
         string s,v;//s存商,v存余数
         int a[L],b[L],r[L],La=n1.size(),Lb=n2.size(),i,tp=La;
         //a,b是整形数组表示被除数,除数,tp保存被除数的长度
         fill(a,a+L,0);fill(b,b+L,0);fill(r,r+L,0);//数组元素都置为0
         for(i=La-1;i>=0;i--) a[La-1-i]=n1[i]-'0';
         for(i=Lb-1;i>=0;i--) b[Lb-1-i]=n2[i]-'0';
         if(La<Lb || (La==Lb && n1<n2)) {
                //cout<<0<<endl;
         return n1;}//如果a<b,则商为0,余数为被除数
         int t=La-Lb;//除被数和除数的位数之差
         for(int i=La-1;i>=0;i--)//将除数扩大10^t倍
            if(i>=t) b[i]=b[i-t];
            else b[i]=0;
         Lb=La;
         for(int j=0;j<=t;j++) {
             int temp;
             while((temp=sub(a,b+j,La,Lb-j))>=0) {
                 La=temp;
                 r[t-j]++;
             }
         }
         for(i=0;i<L-10;i++) r[i+1]+=r[i]/10,r[i]%=10;//统一处理进位
         while(!r[i]) i--;//将整形数组表示的商转化成字符串表示的
         while(i>=0) s+=r[i--]+'0';
         i=tp;
         while(!a[i]) i--;//将整形数组表示的余数转化成字符串表示的</span>
         while(i>=0) v+=a[i--]+'0';
         if(v.empty()) v="0";
         if(nn==1) return s;//返回商 
         if(nn==2) return v;//返回余数 
    }
    View Code

    高精度除单精度

    string div(string a,int b) {
        string r,ans;
        int d=0;
        if(a=="0") return a;//特判
        for(int i=0;i<a.size();i++) {
                r+=(d*10+a[i]-'0')/b+'0';//求出商
                d=(d*10+(a[i]-'0'))%b;//求出余数
        }
        int p=0;
        for(int i=0;i<r.size();i++)
        if(r[i]!='0') {p=i;break;}
        return r.substr(p);
    }
    View Code

    高精度阶乘

    string fac(int n) {
        const int L=100005;
        int a[L];
        string ans;
        if(n==0) return "1";
        fill(a,a+L,0);
        int s=0,m=n;
        while(m) a[++s]=m%10,m/=10;
        for(int i=n-1;i>=2;i--){
            int w=0;
            for(int j=1;j<=s;j++) a[j]=a[j]*i+w,w=a[j]/10,a[j]=a[j]%10;
            while(w) a[++s]=w%10,w/=10;
        }
        while(!a[s]) s--;
        while(s>=1) ans+=a[s--]+'0';
        return ans;
    }
    View Code
  • 相关阅读:
    【蓝桥杯】基础练习 十六进制转十进制
    【蓝桥杯】 基础练习 十六进制转八进制
    【蓝桥杯】 入门训练 序列求和
    【蓝桥杯】 入门训练 圆的面积
    【蓝桥杯】入门训练 Fibonacci数列
    6次考试小结
    搜索
    sudoku
    生日蛋糕
    木棒
  • 原文地址:https://www.cnblogs.com/iwomeng/p/11660892.html
Copyright © 2011-2022 走看看