【纪中oj 】C组 最大公约数

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

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

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

样例输入
18
24

样例输出
6

数据范围限制
在40%的数据中,1 ≤ A,B ≤ 10^6
在60%的数据中,1 ≤ A,B ≤ 10^18
在80%的数据中,1 ≤ A,B ≤ 10^100
在100%的数据中,1 ≤ A,B ≤ 10^1000


 

这一题我一开始想到用辗转相除法+高精,结果超时
这题用辗转太慢了,所以涉及到一个伟大的算法——更相减损法
如果两个数为偶数 结果乘2,两个数分别除以2
如果一偶一奇,偶数除以2,奇数不变
如果两个奇数,大的减去小的,保留小的
如果用辗转,要用高精除以高精,这样肯定超时
如果用迭代,只需打高精除低精就好了
(原谅我变量名过于庸俗)//2020.8改高级了

string gcd(string a,string b){//迭代
    string p;
    if(a.size()<b.size()||(a.size()==b.size()&&a<b)) swap(a,b);
    if(a==b) return a;
    else if(even_numbers(a)==false&&even_numbers(b)==false)    p=gcd(jian(a,b),b);
    else if(even_numbers(a)==true&&even_numbers(b)==false) p=gcd(chu(a,2),b);
    else if(even_numbers(a)==false&&even_numbers(b)==true) p=gcd(a,chu(b,2));
    else p=cheng("2",gcd(chu(a,2),chu(b,2)));  
    return p;
}

全部代码如下↓

 1 #include<iostream>
 2 #include<string>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 string A,B;
 7 bool even_numbers(string x){//判断偶数
 8     if(x[x.size()-1]=='0'||x[x.size()-1]=='2'||x[x.size()-1]=='4'||x[x.size()-1]=='6'||x[x.size()-1]=='8') return true;
 9     else return false;
10 }
11 string chu(string a,int b){//高精除以低精
12     string jg1="";
13     int i,zs=0,jg;
14     for(i=0;i<=a.size()-1;i++){
15         zs=zs*10+char(a[i]-48);
16         jg=zs/b;
17         jg1=jg1+char(jg+48);
18         zs=zs%b;
19     }   
20     while(jg1[0]=='0'&&jg1.size()>1) jg1.erase(0,1);
21     return jg1;
22 }
23 
24 string cheng(string a,string b){//高精乘
25     int l=0,a1[1001]={0},b1[1001]={0},c1[1001]={0},p,jw,i,j;
26     string ans="";
27     for(i=1;i<=a.size();i++) a1[i]=int(a[a.size()-i]-48);
28     for(i=1;i<=b.size();i++) b1[i]=int(b[b.size()-i]-48);
29     for(i=1;i<=a.size();i++){
30         jw=0;
31         for(j=1;j<=b.size();j++){
32             p=c1[i+j-1];
33             c1[i+j-1]=(c1[i+j-1]+a1[i]*b1[j]+jw)%10;
34             jw=(p+a1[i]*b1[j]+jw)/10;
35         }
36         c1[j+i-1]+=jw;
37     }
38     l=i+j-2;
39     while(c1[l]==0) l--;
40     for(i=1;i<=l;i++) ans=char(c1[i]+48)+ans;
41     return ans;
42 } 
43 string jian(string a,string b){//高精减
44     string t,jg="";
45     int i,n=0,max=0,j,k,c=0,l,y=0,o=0;
46     int a1[100001]={0},b1[100001]={0},c1[100001]={0};
47     if(a.size()<b.size()||(a.size()==b.size()&&a<b)){
48             t=a;
49             a=b;
50             b=t;
51             o=1;
52         }
53         for(i=1;i<=a.size();i++) a1[i]=int(a[a.size()-i]-48);
54         for(j=1;j<=b.size();j++) b1[j]=int(b[b.size()-j]-48);
55         for(k=1;k<=i-1||k<=j-1;k++){
56             c1[k]=a1[k]-b1[k];
57             if(c1[k]<0){
58                 c1[k]+=10;
59                 a1[k+1]--;
60             }
61         }
62         if(o==1) jg="-";
63         while(c1[k-1]==0&&k!=2) k--;
64         for(i=k-1;i>0;i--) jg=jg+char(c1[i]+48);
65             return jg;
66 }
67 string gcd(string a,string b){//迭代
68     string p;
69     if(a.size()<b.size()||(a.size()==b.size()&&a<b)) swap(a,b);
70     if(a==b) return a;
71     else if(even_numbers(a)==false&&even_numbers(b)==false)    p=gcd(jian(a,b),b);
72     else if(even_numbers(a)==true&&even_numbers(b)==false) p=gcd(chu(a,2),b);
73     else if(even_numbers(a)==false&&even_numbers(b)==true) p=gcd(a,chu(b,2));
74     else p=cheng("2",gcd(chu(a,2),chu(b,2)));  
75     return p;
76 77 int main(){
78     freopen("gcd.in","r",stdin);
79     freopen("gcd.out","w",stdout);
80     cin>>A>>B;
81     cout<<gcd(A,B);
82 }

 

posted @ 2020-08-15 15:37  latent_Lin  阅读(261)  评论(4)    收藏  举报