拓展欧几里德算法

EXGCD

核心思想

这是一个求解 (a * x + b * y = gcd(a, b)) 方程的算法。

我们知道 (a * x + b * y = gcd(a, b) = gcd(b, a \% b)),对其展开,也就是。

  • (a * x + b * y)

  • (= b * x + (a \% b) * y)

  • (= b * x + (a - a / b * b) * y)

  • (= a * y + (x - a / b * y) * b)

(b = 0) 的时候也就是 (a * x + b * y = gcd(a, b) = a) 得到x = 1, y = 0

我们就是通过这个关系去不断地递归,最后求解得到这个方程组的解。

代码

/*
    Code by lifehappy 2020:04:22
*/
#include<bits/stdc++.h>
using namespace std;
int exgcd(int a, int b, int &x, int &y) {
    if(!b) {
        x = 1;
        y = 0;
        return a;
    }
    int gcd = exgcd(b, a % b, x, y);
    int temp = x;
    x = y;
    y = temp - a / b * y;
    return gcd;
}
int main() {
    int a, b, x, y;
    while(cin >> a >> b) {
        int gcd = exgcd(a, b, x, y);
        printf("%d %d %d
", gcd, x, y);
    }
}

利用其求解二元一次方程

设有方程 (a* x + b * y = c)

我们知道这个方程有界的充要条件就是 (gcd(a, b) mid c)

代码

/*
    Code by lifehappy 2020:04:22
*/
#include<bits/stdc++.h>
using namespace std;
int exgcd(int a, int b, int &x, int &y) {
    if(!b) {
        x = 1;
        y = 0;
        return a;
    }
    int gcd = exgcd(b, a % b, x, y);
    int temp = x;
    x = y;
    y = temp - a / b * y;
    return gcd;
}
int main() {
    int a, b, c, x, y;
    while(cin >> a >> b >> c) {
        int gcd = exgcd(a, b, x, y);
        if(c % gcd) puts("NO ANSWER");
        else printf("%d * %d + %d * %d = %d
", a, c / gcd * x, b, c / gcd * y, c);
    }
}
原文地址:https://www.cnblogs.com/lifehappy/p/12757346.html