【纪中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 }

浙公网安备 33010602011771号