高精度gcd(P2152 SuperGCD)

更相损减法

   初始化r=0,求gcd(a,b):

   a!=b时,如果a、b都为偶数,a、b都除以2,r++;如果其中一个为偶数,偶数除以2;如果两个都为奇数,大数减去小数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char ar[20000],br[20000];
struct Str
{
    int c[20000],l;
}a,b;
bool equ(Str &a,Str &b)
{
    if(a.l!=b.l)
    return 0;
    for(int i=0;i<a.l;++i)
    {
        if(a.c[i]!=b.c[i])
        return 0;
    }
    return 1;
}
void div(Str &a)
{
    for(int i=a.l-1;i>=0;--i)
    {
        if(a.c[i]&1)
            a.c[i-1]+=10;
        a.c[i]>>=1;
    }
    while(a.c[a.l-1]==0)
        a.l--;
}
bool com(Str &a,Str &b)
{
    if(a.l!=b.l)
        return a.l>b.l;
    for(int i=a.l-1;i>=0;--i)
    {
        if(a.c[i]>b.c[i])
        return 1;
        if(a.c[i]<b.c[i])
        return 0;
    }
}
void mul(Str &a)
{
    int t=0;
    for(int i=0;i<a.l;++i)
    {
        a.c[i]<<=1;
        a.c[i]+=t;
        t=a.c[i]/10;
        a.c[i]%=10;
    }
    if(t)
    {
        a.c[a.l++]=t;
        t=0;
    }
}
void sub(Str &a,Str &b)
{
        for(int i=0;i<a.l;++i)
        {
            if(a.c[i]>=b.c[i])
            a.c[i]-=b.c[i];
            else
            {
                a.c[i+1]--;
                a.c[i]=a.c[i]+10-b.c[i];
            }
        }
        while(a.c[a.l-1]==0)
        a.l--;
}
void show(Str &a)
{
    for(int i=0;i<a.l;++i)
        cout<<a.c[i]<<' ';
    cout<<endl;
}
int main()
{
  //  freopen("1.txt","r",stdin);
    int la,lb;
    scanf("%s%s",ar,br);
    la=strlen(ar),lb=strlen(br);
    int ia=0,sum=0;
    for(int i=la-1;i>=0;--i)
    a.c[ia++]=ar[i]-'0';
    ia=0;
    for(int i=lb-1;i>=0;--i)
    b.c[ia++]=br[i]-'0';
    a.l=la;b.l=lb;
    while(!equ(a,b))
    {
    if(!(a.c[0]&1)&&!(b.c[0]&1))
    {
    sum++;
    div(a);
    div(b);
    }
    else if(!(a.c[0]&1))
    div(a);
    else if(!(b.c[0]&1))
    div(b);
    else if(com(a,b))
    sub(a,b);
    else
    sub(b,a);
    }
    while(sum--)
        mul(a);
    ia=0;
    for(int i=a.l-1;i>=0;--i)
    ar[ia++]=a.c[i]+'0';
    ar[ia++]='\0';
    printf("%s\n",ar);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值