題目鏈接:https://www.acwing.com/problem/content/224/
解題思路:
對於這道題目,首先可以列出這個等式:y + n k = x + mk + Lu;
然後進行移項得到:(n - m)k - uL = x - y;
注意這裏的符號,不管符號是正還是符號都可以直接套用exgcd;
需要注意的是:只有當(x - y) % (n - m, L) == 0的時候,這個方程纔有解集。
對於這道題目,我們通過exgc得到k之後,我們還需要讓k *= (x - y) / d;因爲exgcd得到的X0針對的情況是等式的左邊剛好是(a, b)的時候,所以我們需要乘上一個數;
然後這道題目要求最少的步數,其實對於方程來說就是求最小的正的x;而所有的解集:x = X0 + h(b / d);
需要注意這裏的b / d可能是一個負數,但是我們在求其解集的時候是正數還是負數是沒有任何影響的,因爲h可以取任意的整數,由於這道題目想要求得是最小的而且是正數,所以我們需要取得b / d的絕對值,然後讓 x = (x % tmp + tmp) % tmp;即可。
代碼一份:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
LL xx, yy, m, n, l;
inline LL gcd(LL x, LL y) {
return y == 0 ? x : gcd(y, x % y);
}
inline LL exgcd(LL a, LL b, LL& x, LL& y) {
if(!b) {
x = 1, y = 0;
return a;
}
LL d = exgcd(b, a % b, y, x);
y = y - a / b * x;
return d;
}
int main(void) {
// freopen("in.txt", "r", stdin);
scanf("%lld%lld%lld%lld%lld", &xx, &yy, &m, &n, &l);
if((yy - xx) % gcd(m - n, l)) puts("Impossible");
else {
LL x, y;
LL d = exgcd(m - n, l, x, y);
x *= (yy - xx) / d;
LL tmp = abs(l / d);
x = (x % tmp + tmp) % tmp;
printf("%lld\n", x);
}
return 0;
}