欧几里得算法(又称辗转相除法):主要用于求最大公约数
r = a (mod b)
gcd(a,b)=gcd(b,r);
算法
int euclid(int a,int b)//递归算法
{
if(b==0)
return a;
else
return euclid(b,a%b);
}
int main()//非递归算法
{
int a,b,r;
cin>>a>>b;
while(b)
{
r=a%b;
a=b;
b=r;
}
cout<<"最大公约数为"<<a<<endl;
return 0;
}
扩展欧几里德算法
x*a+y*b=gcd(a,b)=gcd(b,a%b)=x*b+y*(a%b)=x*b+y*(a-a/b*b)=a*y+b*(x-a/b*y)
其中:x=y; y=x-a/b*y;
算法
int ex_gcd(int a,int b,int &x,int &y)
{
int tmp,ret;
if(!b)
{
x=1; y=0; return a;
}
ret=ex_gcd(b,a%b,x,y);
tmp=x; x=y; y=tmp-a/b*y;
return ret;
}
注:由ex_gcd()函数求得的x仅仅是当c=1时的值
还需进行近一步处理 d=gcd(a,b);
x=x*c/b;
s=b/d;
x=(x%s+s)%s;
如 poj1061题
#include <iostream>
using namespace std;
long long ex_gcd(long long a,long long b,long long &x,long long &y)
{
long long ret,tmp;
if(!b)
{
x=1;y=0;return a;
}
else
{
ret=ex_gcd(b,a%b,x,y);
tmp=x;
x=y;
y=tmp-a/b*y;
}
return ret;
}
int main()
{
long long a,b,m,n,l,d;
long long x,y;
while(cin>>a>>b>>m>>n>>l)
{
d=ex_gcd(n-m,l,x,y);
if((a-b)%d||m==n)
cout<<"Impossible"<<endl;
else
{
x=x*(a-b)/d;
int s=l/d;
x=(x%s+s)%s;
cout<<x<<endl;
}
}
return 0;
}