1. gcd ( a , b ) = gcd ( b , a % b )
辗转相除法求最大公约数:
int gcd ( int a , int b ) //a,b不同时为0
{
if ( b== 0 ) return a;
else return gcd ( b , a % b );
}
利用最大公约数求最小公倍数:
int lcm ( int a , int b )
{
if ( a * b ==0 ) return 0;
else return a * b / gcd ( a , b );
}
求 ab mod n:
int modExp ( int a , int b , int n)
{
int t = 1 , y = a ;
while ( b != 0 )
{
if ( b % 2 == 1 ) { t = t * y % n ; }
y = y * y % n ; b = b / 2 ;
}
return t ;
}
2. 若 gcd ( a , b ) = 1 ,则 a ,b 互素( Relative Prime ).
注意:a 与 b 本身不一定是素数
gcd 用法: 1.传球游戏
N个人围圈传球,开始以第一个人拿球,传给左手第 K 个人,满足 1<= k <= N/2 ,求 K 的最大值,使第一个人重新拿到球之前,每个人都拿过球。
Input: 整数N( 3 <= N <= 10200 ) Output: K 的最大值
方法一: 枚举,满足条件的最大互素数(考虑 N 能否整除 K );
方法二:三个判断条件: 1. 若 N 为奇数,则其最大互素数 K = ( N - 1 ) / 2 ;
2. 若 N 为偶数,n/2为偶,则 K = n / 2 - 1 ; 若 n / 2 为奇,则 K = n / 2 - 2 .( 求离它最近的奇数 )
代码如下:
2. d = gcd ( a , b ) = ax + by 可以求出 x 和 y.
如果 b = 0,则 x = 1, y = 任何数;如果 b 不等于 0,则迭代求解。
令 m = a % b,则 gcd ( b , a%b ) = bx' + my' ; 又因为 a % b = a - La/b」b ;
d= bx' + ( a - La/b」b ) y'= bx' + ay' - La/b」by' = b ( x' - La/b」y') + ay'.
可得 x = y', y = x' - La/b」y'.
由这个得出扩展的欧几里德算法:
int exgcd ( int a, int b, int &x, int &y)
{
int r, t;
if ( b==0 ) { x=1; y=0; return a; }
r=exgcd ( b, a%b, x, y);
t=x; x=y; y=t-a/b*y;
return r;
}