zoukankan      html  css  js  c++  java
  • 欧几里得 与 扩展欧几里得

    欧几里得算法

    又称辗转相除法,用来计算两个数的最大公约数

    int gcd(int a, int b){
        if(b==0)
            return a;
        else
            return gcd(b,a%b);
    }

    gcd函数的基本性质

    gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)

    gcd(a,b)=gcd(b,a mod b)

    扩展欧几里得

    扩展欧几里德算法是用来在已知a, b求解一组x,y使得ax+by = Gcd(a, b) =d

    对于不完全为0的非负整数,a,b,必然存在无数对整数对x,y,使得ax+by=gcd(a,b)
    int exgcd(int a, int b)//拓展欧几里德
    {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return a;
        }
        int d = exgcd(b, a%b);
        int t = x;
        x = y;
        y = t - a/b*y;
        return d;
    }

    证明:

    设a*x + b*y= gcd(a,b)   下一个状态 b*x1 + (a%b)*y1 = gcd(b,a%b)

    a%b = a - (a/b)*b

    gcd(b,a%b) = b*x1 + (a-(a/b)*b)*y1

                      = b*x1 + a*y1 – (a/b)*b*y1

                      = a*y1 + b*(x1 – a/b*y1)

    根据朴素欧几里得算法得:

    gcd(a,b) = gcd(b,a mod b) 所以得a*y1 + b*(x1 – a/b*y1) =a*x+b*y

    x = y1

    y = x1 – a/b*y1

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 int a, b, x, y;
     6 int gcd(int m, int n)//欧几里德
     7 {
     8     int t;
     9     while(n)
    10     {
    11         t = n;
    12         n = m % n;
    13         m = t;
    14     }
    15     return m;
    16 }
    17 
    18 //int gcd(int a, int b){
    19 //    if(b==0)
    20 //        return a;
    21 //    else
    22 //        return gcd(b,a%b);
    23 //}
    24 
    25 int exgcd(int a, int b)//拓展欧几里德
    26 {
    27     if(b == 0)
    28     {
    29         x = 1;
    30         y = 0;
    31         return a;
    32     }
    33     int d = exgcd(b, a%b);
    34     int t = x;
    35     x = y;
    36     y = t - a/b*y;
    37     return d;
    38 }
    39 
    40 int main()
    41 {
    42     int a, b;
    43     while(~scanf("%d%d",&a, &b))
    44     {
    45         printf("%d
    ",gcd(a, b));
    46         int g = exgcd(a, b);
    47         if(g == 1)//ax + by = 1
    48         {
    49             while(x < 0)
    50             {
    51                 x += b;
    52                 y -= a;
    53             }
    54             printf("%d %d
    ",x,y);//x>0最小整数解
    55         }
    56         else
    57             printf("sorry
    ");
    58     }
    59     return 0;
    60 }

    扩展欧几里得最大的应用就是求乘法逆元 (a*m)%b=1 称m为

    ma+nb=1 m为a模b的乘法逆元 n为b模a的逆元

    例:http://www.cnblogs.com/wudi-accept/p/5350233.html

  • 相关阅读:
    仿当当网鼠标经过图片翻转
    静态随鼠标移动的Tip
    Weblogic免项目名
    weblogic中文乱码问题
    IE6下的{clear:both}出现怪异的空白
    动态随鼠标移动的Tip
    base标签在ie6下的恶心问题
    javascript中for和for in 区别
    jQuery性能优化<<转>>
    Ant项目打包脚本
  • 原文地址:https://www.cnblogs.com/wudi-accept/p/5350223.html
Copyright © 2011-2022 走看看