long long gcd( long long x, long long y )
{
if( y== 0 )
return x;
return gcd( y, x% y );
}
我们知道a%b = a - (a/b)*b(这里的”a/b“是指整除,例如5/2=2),那么:
gcd = b*x1 + (a-(a/b)*b)*y1
= a*y1 + b*(x1 – a/b*y1)
由此,我们得到x=y1,y=x1-a/b*y1.
拓展欧几里德算法也可以用递归编写:
void exgcd( long long a, long long b, long long &x, long long &y )
{
if( b== 0 )
{
x= 1;
y= 0;
return;
}
exgcd( b, a% b, x, y );
long long t= x;
x= y;
y= t- a/ b* y;
return;
}
拓展欧几里得算法可以求出二元方程的通解,但是在实际应用中,通常会要求我们求出通解中的特殊值,接下来,通过例题了解一下拓展欧几里得在实际中的应用。
Time Limit: 1000MS | Memory Limit: 10000K |
Input
Output
Sample Input
1 2 3 4 5
Sample Output
4
#include
#include
using namespace std;
long long gcd( long long x, long long y )
{
if( y== 0 )
{
return x;
}
return gcd( y, x% y );
}
void exgcd( long long a, long long b, long long &x, long long &y )
{
if( b== 0 )
{
x= 1;
y= 0;
return;
}
exgcd( b, a% b, x, y );
long long t= x;
x= y;
y= t- a/ b* y;
return;
}
int main()
{
long long x, y, m, n, l;
while( scanf( "%lld %lld %lld %lld %lld", &x, &y, &m, &n, &l )!= EOF )
{
long long a= n- m, b= l, c= x- y, p, q;
long long d= gcd( a, b );
if( c% d )
{
puts( "Impossible" );
continue;
}
a/= d, b/= d, c/= d;
exgcd( a, b, p, q );
p*= c;
long long ans= p% b;
while( ans< 0 )
{
ans+= b;
}
printf( "%lld\n", ans);
}
return 0;
}