poj1061欧几里德算法

来源:互联网 发布:卖域名的 编辑:程序博客网 时间:2024/06/10 05:41

有三个算法:一是著名很简单的gcd算法

其关键在于证明gcd(a, b) == gcd(b, a mod b)

利用整除性来证明,即gcd(a , b) 整除 gcd(b, a mod b),而gcd(b, a mod b)整除gcd(a ,b)

设d = gcd(a , b),a mod b = a - (a / b ) * b,所以d可以整除a mod b, d可以整除b,所以d可以整除b和a mod b 的各种线性组合。而gcd(b, a mod b)是b 和a mod b 的最小线性组合。所以d可以整除gcd(b, a mod b)。同理也可以证明gcd(b, a mod b) 整除 gcd(a , b)


二是求解线性方程ax + by = gcd(a ,b);

采用的是递归的思路,因为gcd(a ,b ) = gcd (b, a mod b)

所以解出了gcd(b, a mod b) = bx_0 + (a mod b)y_0;的话

那么gcd(a, b) = bx_0 + (a - (a / b) * b) y_0;

所以gcd(a, b) = ay_0 + (x_0 - (a / b ) * y_0);

代码:

/** *DESCRIPTION:The implement of gcd(a ,b) and ax + by = gcd(a , b) *using the equation gcd(a ,b) = gcd(b, a mod b) *gcd(a, 0) = a */int gcd(int a, int b) {    if (b == 0) {        return a;    }    else {        return gcd(b, a % b);    }}void extended_gcd(long long a, long long b, long long &gcd_d, long long &x, long long &y) {    if (b == 0) {        gcd_d = a;        x = 1;        y = 0;    }    else {        extended_gcd(b, a % b, gcd_d, y, x);        y -= (a / b) * x;    }}



三:求解同余模方程

ax == b (mod n)

算法导论上有详细解释

有两个定理:

(一):如果方程有解的话必定有gcd(a, n) | b

(二):如果方程有解的话有n / (gcd(a, n))个解

其中最小正数解为(x0 + n) % (n / d)   (d == gcd(a , n));

其中a, b是否为负数没有影响。

poj1061:

#include <iostream>#include <stdio.h>using namespace std;void extended_eculid(long long a, long long b, long long &gcd_d, long long &x, long long &y) {    if (b == 0) {        gcd_d = a;        x = 1;        y= 0;    }    else {        extended_eculid(b, a % b, gcd_d, y, x);        y -= (a / b) * x;    }}int main() {    long long x, y, m, n, L;    long long a, b, gcd_d, x_0, y_0, ans;    while (scanf("%lld%lld%lld%lld%lld", &x, &y, &m, &n, &L) != EOF) {        a = m - n;        b = y - x;        /*        if (a < 0) {            a = -a;            b = -b;            }*/        extended_eculid(a, L, gcd_d, x_0, y_0);        if ((b % gcd_d) != 0) {            cout << "Impossible" << endl;        }        else {            ans = (x_0 * b / gcd_d) % L;            ans = (ans + L) % (L / gcd_d);            if (ans == 0) {                ans += L;            }            cout << ans << endl;        }    }    return 0;}

其中注意ans = 0的时候要输出长度L!~

 

原创粉丝点击