zoukankan      html  css  js  c++  java
  • 一本通1627【例 3】最大公约数

    1627:【例 3】最大公约数

    时间限制: 1000 ms         内存限制: 524288 KB

    【题目描述】

    给出两个正整数 A,B,求它们的最大公约数。

    【输入】

    输入共两行,第一行一个正整数 A,第二行一个正整数 B。

    【输出】

    在第一行输出一个整数,表示 A,B 的最大公约数。

    【输入样例】

    18
    24

    【输出样例】

    6

    【提示】

    数据范围与提示:

    对于 60% 的数据,1≤A,B≤1018

    对于 100% 的数据,1≤A,B≤103000 。

    sol:Super Gcd,高精。。。

    直接辗转相除肯定优秀到爆炸,所以我们选择辗转相减

    然而直接辗转相减肯定也是优秀到爆炸但是这道题特别水的数据居然让我过了,这还说什么。。。

    对于辗转相减有一个优化,就是对于当前两个数,如果一奇一偶,就把偶数除以2,如果两个偶,就都除以2,把答案*2,如果两奇就辗转相减。

    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');    return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    inline void Read_S(char *S)
    {
        
        int Len=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            ch=getchar();
        }
        while(ch=='0')
        {
            ch=getchar();
        }
        while(isdigit(ch))
        {
            S[++Len]=ch; ch=getchar();
        }
        return;
    }
    const int N=3005;
    const int Base=10000,Power=4;
    char SX[N],SY[N];
    struct BigNum
    {
        int a[N];
        BigNum()
        {
            memset(a,0,sizeof a);
        }
        BigNum(char *S)
        {
            memset(a,0,sizeof a);
            int i,bb,Pos=0,Len=strlen(S+1);
            a[0]=(Len-1)/Power+1;
            for(i=1;i<=Len;i++)
            {
                if((i-1)%Power==0)
                {
                    Pos++; bb=1;
                }
                a[Pos]+=bb*(S[i]-'0');
                bb*=10;
            }
        }
        inline void Print()
        {
            write(a[a[0]]);
            int i;
            for(i=a[0]-1;i>=1;i--)
            {
                if(a[i]<1000) putchar('0');
                if(a[i]<100) putchar('0');
                if(a[i]<10) putchar('0');
                write(a[i]);
            }
        }
        #define P(x) x.Print(),putchar(' ')
        #define Pl(x) x.Print(),putchar('
    ')
    }X,Y;
    inline bool operator<(const BigNum &p,const BigNum &q)
    {
        if(p.a[0]!=q.a[0]) return p.a[0]<q.a[0];
        int i;
        for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i])
        {
            return p.a[i]<q.a[i];
        }
        return false;
    }
    inline bool operator==(const BigNum &p,const BigNum &q)
    {
        if(p.a[0]!=q.a[0]) return false;
        int i;
        for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i])
        {
            return false;
        }
        return true;
    }
    inline BigNum operator-(const BigNum &p,const BigNum &q)
    {
        int i;
        BigNum ans=p;
        for(i=1;i<=q.a[0];i++)
        {
            ans.a[i]-=q.a[i];
            if(ans.a[i]<0)
            {
                ans.a[i]+=Base;
                ans.a[i+1]--;
            }
        }
        while((!ans.a[ans.a[0]])&&ans.a[0]) ans.a[0]--;
        return ans;
    }
    int main()
    {
        freopen("data.in","r",stdin);
        freopen("my.out","w",stdout);
        Read_S(SX);
        reverse(SX+1,SX+strlen(SX+1)+1);
        X=BigNum(SX);
        Read_S(SY);
        reverse(SY+1,SY+strlen(SY+1)+1);
        Y=BigNum(SY);
        while(!(X==Y))
        {
            BigNum p,q;
            if(X<Y)
            {
                p=Y;
                q=X;
            }
            else
            {
                p=X;
                q=Y;
            }
            X=q;
            Y=p-q;
        }
        Pl(X);
        return 0;
    }
    意外水过的辗转相减
    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');    return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    inline void Read_S(char *S)
    {
        
        int Len=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            ch=getchar();
        }
        while(ch=='0')
        {
            ch=getchar();
        }
        while(isdigit(ch))
        {
            S[++Len]=ch; ch=getchar();
        }
        return;
    }
    const int N=3005;
    const int Base=10000,Power=4;
    char SX[N],SY[N];
    struct BigNum
    {
        int a[N];
        BigNum()
        {
            memset(a,0,sizeof a);
        }
        BigNum(char *S)
        {
            memset(a,0,sizeof a);
            int i,bb,Pos=0,Len=strlen(S+1);
            a[0]=(Len-1)/Power+1;
            for(i=1;i<=Len;i++)
            {
                if((i-1)%Power==0)
                {
                    Pos++; bb=1;
                }
                a[Pos]+=bb*(S[i]-'0');
                bb*=10;
            }
        }
        inline void Print()
        {
            write(a[a[0]]);
            int i;
            for(i=a[0]-1;i>=1;i--)
            {
                if(a[i]<1000) putchar('0');
                if(a[i]<100) putchar('0');
                if(a[i]<10) putchar('0');
                write(a[i]);
            }
        }
        #define P(x) x.Print(),putchar(' ')
        #define Pl(x) x.Print(),putchar('
    ')
    }X,Y,Ans;
    inline bool operator<(const BigNum &p,const BigNum &q)
    {
        if(p.a[0]!=q.a[0]) return p.a[0]<q.a[0];
        int i;
        for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i])
        {
            return p.a[i]<q.a[i];
        }
        return false;
    }
    inline bool operator==(const BigNum &p,const BigNum &q)
    {
        if(p.a[0]!=q.a[0]) return false;
        int i;
        for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i])
        {
            return false;
        }
        return true;
    }
    inline BigNum operator-(const BigNum &p,const BigNum &q)
    {
        int i;
        BigNum ans=p;
        for(i=1;i<=q.a[0];i++)
        {
            ans.a[i]-=q.a[i];
            if(ans.a[i]<0)
            {
                ans.a[i]+=Base;
                ans.a[i+1]--;
            }
        }
        while((!ans.a[ans.a[0]])&&ans.a[0]) ans.a[0]--;
        return ans;
    }
    inline BigNum operator*(const BigNum &p,const BigNum &q)
    {
        int i,j;
        BigNum ans; ans.a[0]=max(p.a[0],q.a[0]);
        for(i=1;i<=p.a[0];i++)
        {
            for(j=1;j<=q.a[0];j++)
            {
                ans.a[i+j-1]+=p.a[i]*q.a[j];
                ans.a[i+j]+=ans.a[i+j-1]/Base;
                ans.a[i+j-1]%=Base;
            }
        }
        while(ans.a[ans.a[0]+1]) ans.a[0]++;
        while(!ans.a[ans.a[0]]) ans.a[0]--;
        return ans;
    }
    inline bool Judge_Ou(BigNum p)
    {
        if(!p.a[0]) return 1;
        return (p.a[1]&1)?0:1;
    }
    inline BigNum Div2(BigNum p)
    {
        BigNum ans;
        ans.a[0]=p.a[0];
        int i;
        for(i=p.a[0];i>=1;i--)
        {
            ans.a[i]+=(p.a[i]>>1);
            if(p.a[i]&1) p.a[i-1]+=Base;
        }
        while(!ans.a[ans.a[0]]) ans.a[0]--;
        return ans;
    }
    inline BigNum Mul2(BigNum p)
    {
        BigNum ans;
        ans.a[0]=p.a[0];
        int i;
        for(i=1;i<=p.a[0];i++)
        {
            p.a[i]<<=1;
            if(p.a[i]>Base)
            {
                ans.a[i+1]+=p.a[i]/Base;
                p.a[i]%=Base;
            }
            ans.a[i]+=p.a[i];
        }
        while(ans.a[ans.a[0]+1]) ans.a[0]++;
        return ans;
    }
    int main()
    {
        freopen("data.in","r",stdin);
        freopen("my.out","w",stdout);
        Read_S(SX);
        reverse(SX+1,SX+strlen(SX+1)+1);
        X=BigNum(SX);
        Read_S(SY);
        reverse(SY+1,SY+strlen(SY+1)+1);
        Y=BigNum(SY);
        Ans.a[0]=Ans.a[1]=1;
        while(!(X==Y))
        {
    //        P(X); Pl(Y);
            bool BoX=Judge_Ou(X),BoY=Judge_Ou(Y);
            if(BoX)
            {
                if(BoY)
                {
                    X=Div2(X); Y=Div2(Y); Ans=Mul2(Ans);
                }
                else
                {
                    X=Div2(X);
                }
            }
            else
            {
                if(BoY)
                {
                    Y=Div2(Y);
                }
                else
                {
                    BigNum p,q;    
                    if(X<Y) p=Y,q=X;
                    else p=X,q=Y;
                    X=p-q; Y=q;
                }
            }
        }
        Ans=Ans*X;
        Pl(Ans);
        return 0;
    }
    带优化的正确姿势
  • 相关阅读:
    服务器搭建域控与SQL Server的AlwaysOn环境过程(二) 搭建客户端节点 服务器
    服务器搭建域控与SQL Server的AlwaysOn环境过程(一) 搭建域控服务器
    React中的AES加解密请求
    React项目构建(利用webpack打包)
    解决IIS服务器部署 字体图标找不到的原因
    iOS开发之视频播放31次、15次后错误,NSLocalizedFailureReason=此媒体所需的解码器正忙
    iOS开发之视频播放功能、边播放边缓存
    iOS开发之获取最上层 Window
    iOS开发之APP启动视频
    iOS开发之图片base64编码处理
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10433546.html
Copyright © 2011-2022 走看看