最大公约数(信息学奥赛一本通 1627)

Posted ljy-endl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大公约数(信息学奥赛一本通 1627)相关的知识,希望对你有一定的参考价值。

【题目描述】

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

【输入】

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

【输出】

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

【输入样例】

18
24

【输出样例】

6

【提示】

数据范围与提示:

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

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

 


 首先看到这道题的数据范围之后,我们肯定是得用高精度呐,然后为了方便一点,缩小数组大小,我们还可以引进“压位高精度”,一般来说,最好使用四位压一位,用五位的话容易爆掉...

--->关于“压位高精”,可以去看看这位大佬的博客,感jio讲的很清楚

进入正题,此题要求两个高精的“最大公约数”,那我们肯定会想到用”二进制算法“呐,

--->关于“二进制算法”,可以去看看我的另一篇博客(应该在最后面有讲到),也称更相减损术

那我直接上代码吧(反正是一道模板题...

技术图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e6+5,inf=1<<29,base=10000;//10000而不是100000,不然容易爆掉! 
  4 int T;
  5 int a[1000],b[1000],c[1000],f[1000];
  6 int read()
  7 
  8     int f=1;char ch;
  9     while((ch=getchar())<0||ch>9)
 10         if(ch==-)f=-1;
 11     int res=ch-0;
 12     while((ch=getchar())>=0&&ch<=9)
 13         res=res*10+ch-0;
 14     return res*f;
 15 
 16 void write(int x)
 17 
 18     if(x<0)
 19     
 20         putchar(-);
 21         x=-x;
 22     
 23     if(x>9)write(x/10);
 24     putchar(x%10+0);
 25 
 26 /*int gcd(int x,int y)
 27 
 28     if(y==0)return x;
 29     else return gcd(y,x%y);
 30 */
 31 //欧几里得算法~显然不行 
 32 void init(int a[])//压位高精度 
 33 
 34     string s;
 35     cin>>s;
 36     int len=s.length(),i,j;
 37     for(i=0;i<len;i++)
 38     
 39         j=(len-i+3)/4;//注意是len-i+3,而不是+4! 
 40         a[j]=a[j]*10+s[i]-0;
 41     
 42     a[0]=(len+3)/4;
 43 
 44 int com(int a[],int b[])//比较大小 
 45 
 46     if(a[0]>b[0])return 1;
 47     if(a[0]<b[0])return -1;
 48     for(int i=a[0];i>=1;i--)
 49     
 50         if(a[i]>b[i])return 1;
 51         else if(a[i]<b[i])return -1;
 52     
 53     return 0;
 54 
 55 void div(int a[])//高精除2 
 56 
 57     int tmp=0;
 58     for(int i=a[0];i>=1;i--)
 59     
 60         tmp=tmp*base+a[i];
 61         a[i]=tmp/2;
 62         tmp%=2;
 63     
 64     while(a[a[0]]==0&&a[0]>0)a[0]--;
 65 
 66 void jian(int a[],int b[])//高精减高精 
 67 
 68     for(int i=1;i<=a[0];i++)
 69     
 70         a[i]-=b[i];
 71         if(a[i]<0)
 72         
 73             a[i+1]--;
 74             a[i]+=base;
 75         
 76         while(a[a[0]]==0&&a[0]>0)a[0]--;
 77     
 78 
 79 void gcd(int a[],int b[],int t)//二进制算法 
 80 
 81     if(com(a,b)==0)//如果二者相同,那就是最大公约数无疑了 
 82     
 83         T=t;
 84         return ;
 85     
 86     if(com(a,b)<0)
 87     
 88         gcd(b,a,t);
 89         return ;
 90     
 91     int ta=0,tb=0;
 92     if(a[1]%2==0)
 93     
 94         div(a);
 95         ta=1;
 96     
 97     if(b[1]%2==0)
 98     
 99         div(b);
100         tb=1;
101     
102     if(ta&&tb)gcd(a,b,t+1);
103     else if(!ta&&!tb)
104     
105         jian(a,b);
106         gcd(a,b,t);
107     
108     else gcd(a,b,t);
109 
110 void print(int a[])//高精输出 
111 
112     write(a[a[0]]);
113     for(int i=a[0]-1;i>0;i--)//这里可是有点学问的,不能直接像输出a[a[0]]一样输出其他几位,
114         for(int j=base/10;j>0;j/=10)//因为其他几位可能最高位为0,直接输出则0被吞掉了 
115             write(a[i]/j%10);
116 
117 void mulow(int a[],int k)//高精乘低精 
118 
119     for(int i=1;i<=a[0];i++)a[i]*=k;
120     for(int i=1;i<=a[0];i++)
121     
122         a[i+1]+=a[i]/base;
123         a[i]%=base;
124     
125     while(a[a[0]+1]>0)
126     
127         a[0]++;
128         a[a[0]+1]=a[a[0]]/base;
129         a[a[0]]%=base;
130     
131 
132 void mulhigh(int a[],int b[])//高精乘高精 
133 
134     for(int i=1;i<=a[0];i++)
135         for(int j=1;j<=b[0];j++)
136         
137             c[i+j-1]+=a[i]*b[j];
138             c[i+j]+=c[i+j-1]/base;
139             c[i+j-1]%=base;
140         
141     c[0]=a[0]+b[0];
142     while(c[c[0]]==0&&c[0]>0)c[0]--;
143     for(int i=0;i<=c[0];i++)a[i]=c[i];    
144 
145 int main()
146 
147     init(a);init(b);
148     gcd(a,b,0);
149     if(T==0)print(a);//T存储最大公约数中有多少个2 
150     else 
151     
152         f[0]=f[1]=1;
153         for(int i=1;i<=T;i++)
154             mulow(f,2);//将2累乘 
155         mulhigh(f,a);
156         print(f);
157     
158     return 0;
159 
View Code

 

以上是关于最大公约数(信息学奥赛一本通 1627)的主要内容,如果未能解决你的问题,请参考以下文章

LibreOJ刷题计划 &《信息学奥赛一本通》提高版题目

信息学奥赛一本通要多少钱

信息学奥赛一本通Part1.2 基础算法-二分与三分

信息学奥赛一本通为啥不通过

一本通1627例 3最大公约数

长春市哪里有卖这本信息学奥赛一本通c++的书店?