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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值