问题 A: 最大公约数

链接:http://acm.ocrosoft.com/problem.php?cid=1702&pid=0

题目描述

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

输入

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

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

输出

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

样例输入

18

24

样例输出

6

思路:

这道题是一道大数的约数题,用普通的辗转相除法肯定会TLE因此我们要用大数的转转相除法

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#define inf 1000000000

using namespace std;

char ch1[10005],ch2[10005];

int la,lb,cnt;

struct data{

int a[1205],l;

}a,b;//建立结构体,a数组存数字,l表示长度

bool com()//比较函数,比较两个数大小

{

    if(a.l<b.l)

return 0;

    if(a.l>b.l)

return 1;

    for(int i=a.l;i>0;--i)

        if(a.a[i]>b.a[i])

return 1;

        else if(a.a[i]<b.a[i])

return 0;

    return 1;

}

void print(data a)//输出函数

{

    while(a.a[a.l]==0)

a.l--;

    for(int i=a.l;i>0;--i)

        if(i==a.l)

printf("%d",a.a[i]);

        else printf("%09d",a.a[i]);

}

inline data sub(data a,data b)//高精度辗转相除法

{

    int k;

    data c;//用于记录中间值,以及最后输出结果

    for(int i=1;i<=1200;++i)

    {

       if(i<=b.l)

   c.a[i]=a.a[i]-b.a[i];

       else if(i<=a.l)

   c.a[i]=a.a[i];

       else

   c.a[i]=0;

       if(c.a[i]<0)

       {

          c.a[i]+=inf;

          a.a[i+1]--;

       }

    }

    c.l=a.l;

    while(c.a[c.l]==0&&c.l)//除去前导零

c.l--;

    return c;

}

void diva()//去2操作

{

    for(int i=1;i<=a.l;i++)

    {

        if(a.a[i]&1)a.a[i-1]+=inf/2;

        a.a[i]>>=1;

    }

    if(!a.a[a.l])

a.l--;

}

void divb()

{

    for(int i=1;i<=b.l;i++)

    {

        if(b.a[i]&1)b.a[i-1]+=inf/2;

        b.a[i]>>=1;

    }

    if(!b.a[b.l])

b.l--;

}

void mul()//重新将2加回

{

    for(int i=a.l;i>0;i--)

    {

       a.a[i]<<=1;

       a.a[i+1]+=a.a[i]/inf;

       a.a[i]%=inf;

    }

    while(a.a[a.l]>0)

a.l++;

    for(int i=b.l;i>0;i--)

    {

       b.a[i]<<=1;

       b.a[i+1]+=b.a[i]/inf;

       b.a[i]%=inf;

    }

    while(b.a[b.l]>0)

b.l++;

}

int main()

{

    scanf("%s%s",ch1+1,ch2+1);

    la=strlen(ch1+1);

lb=strlen(ch2+1);

    if(la%9)

a.l=la/9+1;//以九位为单位,分割大数

    else

a.l=la/9;

    if(lb%9)

b.l=lb/9+1;

    else

b.l=lb/9;

    for(int i=1;i<=a.l;++i)

    {

        int k1=max(1,la-i*9+1),k2=la-(i-1)*9;

        for(int j=k1;j<=k2;++j)

        a.a[i]=a.a[i]*10+ch1[j]-'0';

    }

    for(int i=1;i<=b.l;++i)

    {

        int k1=max(1,lb-i*9+1),k2=lb-(i-1)*9;

        for(int j=k1;j<=k2;++j)

        b.a[i]=b.a[i]*10+ch2[j]-'0';

    }

    while(1)

    {

        if((a.a[1]%2==0)&&(b.a[1]%2==0))

{

diva();

divb();

cnt++;

}

        else if((a.a[1]%2==0))

diva();

        else if((b.a[1]%2==0))

divb();

        if(com())

{

a=sub(a,b);

if(!a.l)

{

while(cnt--)

mul();

print(b);

break;

}

}

        else

{

b=sub(b,a);

if(!b.l)

{

while(cnt--)

mul();

print(a);

break;

}

}

    }

    return 0;

 

全部评论

相关推荐

zzzilik:四个月实习做了3个项目不觉得很假吗,真没必要写这么多吧我感觉挑点核心的重点写一下我感觉会好点
你的简历改到第几版了
点赞 评论 收藏
分享
12-08 07:42
门头沟学院 Java
27届末九,由于是女生,身边人几乎没有就业导向的,自学只能跟着网课,没人指导,很迷茫。下图是我目前的简历,不知道有需要修改的地方吗?求拷打。下面是目前的学习情况:目前算法过完了一遍力扣100和代码随想录,不过不是很熟,面经看了小林coding、JavaGuide,有一些没用过的技术看得不是很明白,掌握得不是很扎实。再加上常年跟黑马网课听思路,真正自己动手写代码的时间很少,这让我一直不敢投简历,总觉得内里空虚。项目没准备好面试相关的问题,简历上相应的考点不熟。如此种种。。。看到很多很多学长学姐大佬们的面经,愈发觉得面试可怕,自己没准备好,总担心自己是不是无望后端开发了。看到牛客很多同届以及更小一届的同学都找到实习了,很希望自己也能找到实习。而自己又好像摸不到后端学习的门路,只能不断赞叹黑马虎哥写的代码真优雅!微服务架构实在巧妙!消息队列、redis、sentinel、nacos、mybatisplus等等的引入都会让我赞叹这些工具的设计者的巧思,以及包括但不限于Java语言的优雅。然而只是停留在了解的程度,并不熟练。我是很希望能够继续深入探索这些知识的,只不过有一大部分时间都花在学校课程上了。我感觉我被困住了,我一方面必须保证我能够有个不错的学业分使我能有我几乎不想选择的读研退路(还有个原因是复习不全我会焦虑考试挂科,因此我会做好全面的准备,而这一步很费时间),一方面在B站学习各种网课,一方面得考虑提升自己并不扎实的算法基础,另一方面还得准备八股面经。这让我有点苦恼,我好像没那么多时间,因为绝大部分时间都花在了复习学校科目中了。我好像处处用时间,但收效甚微。想问问各位大佬是怎么平衡时间的呢?算法、项目和八股是怎么准备的呢?有什么高效的方法吗?谢谢您们花时间阅读我的稿件!
菜菜狗🐶:大胆投,我当时也是害怕面试,投多了发现根本约不到面🤡
投递哔哩哔哩等公司6个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务