zoukankan      html  css  js  c++  java
  • 大整数乘法(分治法)

    题目:输入两个大整数,用数组保存每一位数,然后用分治法计算;

    思路:输入X Y,X高位用A数组保存,低位用B数组保存,Y高位用C数组保存,低位用D数组保存,则:X=A*10^(n/2)+B  Y=C*10^(n/2)+D 

            分治方法:X*Y=A*C*10^n+((A-B)*(D-C)+A*C+B*D)*10^(n/2)+B*D;

    代码如下:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <map>
    #include <vector>
    using namespace std;
    
    void add(int a[],int b[],int c[])
    {
        int tot=0;
        int maxn=max(a[0],b[0]);
        for(int i=2; i<=maxn+2; i++)
        {
            c[i]=(a[i]+b[i]+tot)%10;
            tot=(a[i]+b[i]+tot)/10;
        }
        c[0]=maxn+(c[maxn+2]>0);
        c[1]=a[1];
    }
    void sub(int a[],int b[],int c[])
    {
        int tot=0;
        int maxn=max(a[0],b[0]);
        c[1]=1;
        for(int i=maxn+1; i>=2; i--)
        {
            if(a[i]>b[i])  break;
            if(a[i]<b[i])
            {
                swap(a,b);
                c[1]=-1;
                break;
            }
        }
        for(int i=2; i<=maxn+1; i++)
        {
            c[i]=a[i]+tot-b[i];
            if(c[i]<0)
            {
                c[i]=c[i]+10;
                tot=-1;
            }
            else tot=0;
        }
        c[0]=a[0];
    }
    void process(int a[],int b[],int c[],int g)
    {
        if(a[1]>0)
        {
            if(b[1]*g>0)  add(a,b,c);
            else      sub(a,b,c);
        }
        else
        {
            if(b[1]*g>0)  sub(b,a,c);
            else      add(a,b,c);
        }
    }
    void Move(int a[],int n)
    {
        for(int i=a[0]+1; i>=2; i--)
            a[i+n]=a[i];
        for(int i=2; i<=n+1; i++)
            a[i]=0;
        a[0]+=n;
    }
    void print(int c[])
    {
        int i;
        if(c[1]<0) cout<<"-";
        for(i=c[0]+1; i>=2; i--)
            if(c[i]) break;
        for(; i>=2; i--)
            cout<<c[i];
        cout<<endl;
    }
    void duiqi(int a[],int b[])
    {
        int maxn=max(a[0],b[0]);
        int tmp=1;
        for(int i=0;i<=10;i++)
        {
            if(tmp>=maxn) break;
            tmp<<=1;
        }
        a[0]=tmp;
        b[0]=tmp;
    }
    void calc(int a[],int b[],int c[])
    {
        if(a[0]==1)
        {
            int tmp=a[2]*b[2];
            c[0]=1;
            c[2]=tmp%10;
            if(tmp>=10)
            {
                c[3]=tmp/10;
                c[0]++;
            }
            c[1]=a[1]*b[1];
            return;
        }
    
        int A[1000],B[1000],C[1000],D[1000],E[1000],F[1000];
        int m1[1000],m2[1000],m3[1000];
        memset(A,0,sizeof(A));
        memset(B,0,sizeof(B));
        memset(C,0,sizeof(C));
        memset(D,0,sizeof(D));
        memset(E,0,sizeof(E));
        memset(F,0,sizeof(F));
        memset(m1,0,sizeof(m1));
        memset(m2,0,sizeof(m2));
        memset(m3,0,sizeof(m3));
        for(int i=1; i<=a[0]/2+1; i++)
            B[i]=a[i];
        B[0]=a[0]/2;
        for(int i=a[0]/2+2; i<=a[0]+1; i++)
            A[i-a[0]/2]=a[i];
        A[0]=a[0]/2;
        A[1]=a[1];
    
        for(int i=1; i<=b[0]/2+1; i++)
            D[i]=b[i];
        D[0]=b[0]/2;
        for(int i=b[0]/2+2; i<=b[0]+1; i++)
            C[i-b[0]/2]=b[i];
        C[0]=b[0]/2;
        C[1]=b[1];
        process(A,B,E,-1);
        process(D,C,F,-1);
        calc(A,C,m1);
        calc(E,F,m2);
        calc(B,D,m3);
        process(m2,m1,E,1);
        process(E,m3,F,1);
        Move(m1,a[0]);
        Move(F,a[0]/2);
        process(m1,F,E,1);
        process(E,m3,c,1);
    }
    int main()
    {
        int a[1000],b[1000],c[2000];
        char s1[1000],s2[1000];
        cin>>s1>>s2;
        a[0]=strlen(s1)-1;
        if(s1[0]=='-') a[1]=0;
        else       a[1]=1;
        a[0]+=a[1];
        for(int i=2; i<=a[0]+1; i++)
            a[i]=s1[a[0]-a[1]-i+2]-'0';
    
        b[0]=strlen(s2)-1;
        if(s2[0]=='-') b[1]=0;
        else       b[1]=1;
        b[0]+=b[1];
        for(int i=2; i<=b[0]+1; i++)
            b[i]=s2[b[0]-b[1]-i+2]-'0';
        a[1]+=a[1]-1;
        b[1]+=b[1]-1;
        duiqi(a,b);
        calc(a,b,c);
        print(c);
        return 0;
    }
  • 相关阅读:
    让GoogleCode的SVN下的HTML文件在FireFox下正常显示
    添加验证控件出错
    【转载】SQLServer中char、varchar、nchar、nvarchar的区别:
    人生第一篇博客
    二叉排序树
    最小编辑距离
    面试题集锦_4
    面试题集锦_3
    键树
    B树
  • 原文地址:https://www.cnblogs.com/chen9510/p/5876105.html
Copyright © 2011-2022 走看看