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);
}
}