欧几里得算法(数论)

 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 .(  求离它最近的奇数 )

代码如下:

View Code
 1  #include < iostream >
 2  using   namespace  std;
 3  int  main()
 4  {
 5       int  n,k;
 6      cin >> n;
 7       if (n % 2 == 1 ) k = (n - 1 ) / 2 ;
 8       else  {
 9           if (n / 2 % 2 == 0 ) k = n / 2 - 1 ;
10           else  k = n / 2 - 2 ;
11      }
12      cout << k << endl;
13       return   0 ;
14  }

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/bb ;

    d= bx' + ( a - La/bb ) y'= bx' + ay' -  La/bby' = b ( x' - La/by') + ay'.

    可得 x = y', y =  x' - La/by'.

    由这个得出扩展的欧几里德算法:

  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;

}

     


 

你可能感兴趣的:(算法)