1.枚举法
从min(a,b)到1枚举,判断,复杂度O(min(a,b))
2.分解素因数
int Decompose(int a,int b){
int ans = 1;
for(int x = 2; x * x <= min(a,b); x++){
while(a % x == 0 && b % x == 0){a /= x;b /= x;ans *= x;}
while(a % x == 0) a /= x;
while(b % x == 0) b /= x;
}
if(a % b == 0) ans *= b;
else if(b % a == 0) ans *= a;
return ans;
}
3.欧几里得算法(辗转相除法)
int gcd(int a,int b){
if (b == 0) return a;
else return gcd(b,a % b);
}
时间复杂度O(log(a+b))
4.高精度gcd(更相减损术)
不妨设a<=b,则有:
1.a=b时, gcd(a,b)=a;
2.a,b均为偶数时,gcd(a,b)=2*gcd(a/2,b/2);
3.a为偶,b为奇时,gcd(a,b)=gcd(a/2,b);
4.a为奇,b为偶时,gcd(a,b)=gcd(a,b/2);
5.a,b均为奇数时,gcd(a,b)=gcd(a-b,b);
例题
#include<bits/stdc++.h>
#define str strlen
#define ll long long
using namespace std;
struct huge{
int num[10010];
int len;
};
huge a,b;
char d[10010];char c[10010];
void print(huge x){
for(int i=x.len-1;i>=0;i--) cout<<x.num[i];
// cout<<endl;
}
int smp (huge x,huge y){
if(x.len>y.len) return 1;
if(x.len<y.len) return 2;
for(int i=x.len-1;i>=0;i--){
if(x.num[i]>y.num[i]) return 1;
if(x.num[i]<y.num[i]) return 2;
}
return 3;
}
huge ch(huge x){
int plus=0;
for(int i=0;i<=x.len-1;i++){
x.num[i]*=2;
x.num[i]+=plus;plus=0;
if(x.num[i]>=10){
plus=x.num[i]/10;
x.num[i]%=10;
}
}
if(plus!=0){
x.len++;
x.num[x.len-1]=plus;
}
return x;
}
huge chu(huge x){
for(int i=x.len-1;i>=0;i--){
if(x.num[i]%2==1){
x.num[i]--;
x.num[i-1]+=10;
}
x.num[i]/=2;
}
while(x.num[x.len-1]==0&&x.len>1) x.len--;
return x;
}
huge minu(huge x,huge y){
for(int i=0;i<x.len;i++){
if(x.num[i]<y.num[i]){
x.num[i]+=10;
x.num[i+1]--;
}
x.num[i]-=y.num[i];
}
while(x.num[x.len-1]==0&&x.len>1) x.len--;
return x;
}
void gcd(huge x,huge y){
int xx=smp(x,y),aa=1-x.num[0]%2,bb=1-y.num[0]%2;
int tt=0;
while(xx<3){//print(x);print(y);
if(xx==2){
swap(x,y);
swap(aa,bb);
}
if(aa==1&&bb==1){
x=chu(x);y=chu(y);
tt++;
}
if(aa==1&&bb==0) x=chu(x);
if(aa==0&&bb==1) y=chu(y);
if(aa==0&&bb==0) x=minu(x,y);
xx=smp(x,y);aa=1-x.num[0]%2;bb=1-y.num[0]%2;
}
for(int i=1;i<=tt;i++) x=ch(x);
print(x);
return;
}
int main(){
scanf("%s",&c);
scanf("%s",&d);
if(str(c)<str(d)||(str(c)==str(d)&&strcmp(d,c)>0)) swap(c,d);
a.len=str(c);b.len=str(d);
for(int i=0;i<a.len;i++)
a.num[i]=(int)(c[a.len-i-1]-'0');
for(int i=0;i<b.len;i++)
b.num[i]=(int)(d[b.len-i-1]-'0');
gcd(a,b);
return 0;
}