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('\n')
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('\n')
}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('\n')
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('\n')
}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;
}

带优化的正确姿势

转载于:https://www.cnblogs.com/gaojunonly1/p/10433546.html

一本通1627【例 3】最大公约数相关推荐

  1. 一本通【例4-10】最优布线问题

    题目链接 http://ybt.ssoier.cn:8088/problem_show.php?pid=1349 问题描述 学校有n台计算机,为了方便数据传输,现要将它们用数据线连接起来.两台计算机被 ...

  2. 信奥一本通-动态规划-例9.2-数字金字塔-方法四-逆推法代码实现

    #include<bits/stdc++.h> using namespace std;int main(){//x y分别为行列int x, y;//金字塔的高度int n;cin &g ...

  3. 信息学奥赛一本通 2021:【例4.6】最大公约数

    [题目链接] ybt 2021:[例4.6]最大公约数 [题目考点] 1. while循环 2. 求最大公约数 辗转相减法 辗转相除法 [解题思路] 解法1:枚举 取较小数字,从该数字的值开始从大到小 ...

  4. 寻找最大公约数c语言,C语言程序设计100例之(10):最大公约数

    例10        最大公约数 问题描述 有三个正整数a,b,c(0 输入数据 第一行输入一个n,表示有n组测试数据,接下来的n行,每行输入两个正整数a,b. 输出格式 输出对应的c,每组测试数据占 ...

  5. 3 求最大公约数和最小公倍数

    题目描述 输入两个整数,求两个整数的最大公约数和最小公倍数,并输出结果. 设两个整数为u和v,用辗转相除法求最大公约数和最小公倍数的算法如下: if v>u 将变量u与v交换           ...

  6. 信息学奥赛一本通 1209:分数求和 | OpenJudge NOI 1.13 12:分数求和

    [题目链接] ybt 1209:分数求和 OpenJudge NOI 1.13 12:分数求和 [题目考点] 1. 求最大公约数 2. 求最小公倍数 [解题思路] 求最大公约数,可以用辗转相除法.具体 ...

  7. 【经典回放】JavaScript学习详细干货笔记之(一)

    [经典回放]JavaScript学习详细干货笔记之(一) [经典回放]JavaScript学习详细干货笔记之(二) [经典回放]JavaScript学习详细干货笔记之(三) 目录 一.为什么要学Jav ...

  8. c语言第一周作业答案,C语言程序设计下mooc答案.pdf

    <C语言程序设计下mooc答案.pdf>由会员分享,可在线阅读,更多相关<C语言程序设计下mooc答案.pdf(27页珍藏版)>请在装配图网上搜索. 1.2016.03.280 ...

  9. 你的软件也能挣钱 共享软件走向国际指南

    共享软件为何要走向国际? 理由很简单,不少人做共享软件走国际路线,月入数万美元,而同样软件走国内路线恐怕很难达到这个数.(原因大家都知道) 软件开发三个永恒的主题是: 一.软件的功能及创意 二.软件的 ...

最新文章

  1. 从电视到网络,vivo营销之变
  2. Scene Player初始版本完成
  3. Bag of Tricks for Efficient Text Classification论文阅读及实战
  4. android+tv+自动切换,Android TV 重写GridView,实现焦点放大效果
  5. 如何在graphpad表示出正负误差_GraphPad Prism 8.0绘制误差连线并填充颜色图
  6. 在Jenkins中获取GitHub对应Repository的Resource Code
  7. 20145206 《信息安全系统设计基础》第十二周学习总结
  8. 9:04 2009-7-28
  9. ChaiNext:大盘横盘,主流币未有突出表现
  10. usb转rs485测试软件,usb转rs485驱动程序
  11. 物联网产业链全景图(附另13大电子行业全景图,必收藏)
  12. 专访程炳皓:八年一觉“开心”梦
  13. c++,kmin,kmax
  14. 游戏开发入门系列(目录)
  15. [系统与控制]力场盾系统升级原因
  16. 解决Maven无法使用ojdbc依赖的问题
  17. 电脑上怎么压缩PDF文件
  18. JAVA第一次实验 ——凯撒密码
  19. 2021-2027全球与中国城市空中交通市场现状及未来发展趋势
  20. 中国食物链?(看不上,看不起,瞧不起,狗眼看人低)

热门文章

  1. 好的博客地址html
  2. MFC的exe启动时提示应用程序配置不正确,应用程序未能启动错误
  3. ***必备兵器与技能
  4. 怎么样配置交换机TRUNK
  5. 麦当劳java排班_学习肯德基排班管理系统
  6. 基于ASP.Net Core开发的一套通用后台框架
  7. 【ajax 】同步、异步交互流程的区别
  8. TCP/IP协议模型详解
  9. 苹果电脑macbook怎样强制关闭软件
  10. 文本编辑器Nano实用快捷键