Acwing222_青蛙的約會_同餘方程

題目鏈接: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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章