1.欧几里得算法(Euclidean Algorithm)又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。
计算公式: gcd(a,b) = gcd(b , a mod b)
#include <stdio.h>
#include <stdlib.h>
//欧几里德算法
int gcd(int x,int y)
{
int maxn,minn;
maxn=x>y?x:y;
minn=x>y?y:x;
while(minn!=0)
{
int r=maxn%minn;
maxn=minn;
minn=r;
}
return maxn;
}
int main()
{
int x,y;
scanf("%d%d",&x,&y);
int ans=gcd(x,y);
printf("%d",ans);
return 0;
}
2.扩展欧几里得算法(Extended Euclidean algorithm)是欧几里得算法(又叫辗转相除法)的扩展。已知整数x,y,扩展欧几里得算法可以在求得x,y 的最大公约数的同时,能找到整数s、t(其中一个很可能是负数),使它们满足贝祖等式: sx+ty=gcd(x,y) 。
#include <stdio.h>
#include <stdlib.h>
//a[0]=s a[1]=t
int a[4];
//拓展欧几里德算法
void extended_euclid(int x,int y)
{
int r1,r2,s1,s2,t1,t2;
r1=x;s1=1;t1=0;
r2=y;s2=0;t2=1;
while(r2!=0)
{
int q=r1/r2;
int tem1=r1-q*r2;
int tem2=s1-q*s2;
int tem3=t1-q*t2;
r1=r2;s1=s2;t1=t2;
r2=tem1;s2=tem2;t2=tem3;
}
a[0]=s1;a[1]=t1;
}
int main()
{
int x,y;
scanf("%d%d",&x,&y);
extended_euclid(x,y);
printf("s=%d t=%d",a[0],a[1]);
return 0;
}
3.扩展欧几里得算法的应用可以用来计算模反元素(也叫模逆元)。
定义:设m是一个正正整数,a是一个整数,如果存在整数 a’ 使得
aa’ ≡ 1(mod m),成立,则a叫做模m的可逆元,a’叫做模m逆元。在模m的意义下(即m的完全剩余系中)a’存在且唯一。
//求逆 b%m的逆
int extendedeuclid(int m,int b)
{
int a1,a2,a3;
int b1,b2,b3;
int t1,t2,t3;
a1=1;a2=0;a3=m;
b1=0;b2=1;b3=b;
while(1)
{
if(b3==0) return 0;
if(b3==1)
{
if(b2<0) b2=m+b2;
return b2;
}
int q=a3/b3;
t1=a1-q*b1;t2=a2-q*b2;t3=a3-q*b3;
a1=b1;a2=b2;a3=b3;
b1=t1;b2=t2;b3=t3;
}
return 0;
}