【exgcd】P1516 青蛙的约会 题解

题意

两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。

我们把这两只青蛙分别叫做青蛙 A 和青蛙 B,并且规定纬度线上东经 0 0 0 度处为原点,由东往西为正方向,单位长度 1 1 1 米,这样我们就得到了一条首尾相接的数轴。设青蛙 A 的出发点坐标是 x x x,青蛙 B 的出发点坐标是 y y y。青蛙 A 一次能跳 m m m 米,青蛙 B 一次能跳 n n n 米,两只青蛙跳一次所花费的时间相同。纬度线总长 L L L 米。现在要你求出它们跳了几次以后才会碰面。

题意简述

给定 x , y , m , n , l x,y,m,n,l x,y,m,n,l,求 x + k m ≡ y + k n (   m o d   l ) x + km \equiv y + kn(\bmod l) x+kmy+kn(modl) k k k 最小正整数值

思路

x + k m ≡ y + k n (   m o d   l ) x + km \equiv y + kn(\bmod l) x+kmy+kn(modl) 可推出 ( x − y ) + k ( m − n ) ≡ 0 (   m o d   l ) (x - y)+ k(m - n) \equiv0(\bmod l) (xy)+k(mn)0(modl),即 ( x − y ) + k ( m − n ) = p l (x - y)+ k(m - n) = pl (xy)+k(mn)=pl,移项得 k ( m − n ) + p l = x − y k(m - n) + pl = x - y k(mn)+pl=xy,其中 x , y , m , n , l x,y,m,n,l x,y,m,n,l 已知,换元可得 a x + b y = c ax + by = c ax+by=c。因为 m − n m - n mn 可能为负数,所以要进行取反。最后套用 exgcd 求 k k k 最小正整数解即可。

在这里插入图片描述

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int x,y,m,n,l;
int exgcd(int a,int b) {
	if(!b) {
		x = 1,y = 0;
		return a;
	}
	int d = exgcd(b,a % b);
	int  t = x;
	x = y;
	y = t - (a / b) * y;
	return d;
}
signed main() {
	scanf("%lld %lld %lld %lld %lld",&x,&y,&m,&n,&l);
	int a = m - n,b = l,c = -(x - y);
	if(a < 0) {
		a = -a,c = -c; 
	}
	int d = exgcd(a,b);
	if(c % d) {
		printf("Impossible\n");
		return 0;
	}
	x *= c / d;
	int minx = (x % (b / d) + (b / d)) % (b / d);
	if(minx == 0) minx += b / d;
	printf("%lld\n",minx);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值