青蛙的约会 POJ - 1061(拓展欧几里得、线性同余方程)

传送门

先来说题意,两个青蛙,绕着一个长为L的圈跑,青蛙A,B最开始分别位于x,y位置,他们每个单位时间分别可以跑m,n米,问他们是否可以相遇,如果可以相遇的话输出他们所用的最短时间。

假设他们一共跑了t时间,青蛙A,B的总路程分别为mt+x,nt+x,如果们可以相遇的话那么他们的差肯定为圈的长度L的n倍,就可以列出一个关于他们的方程

mt+x-nt-y=pL
变形得到
(m-n)t+pl=y-x

那么他们什么时候没有解呢???对于ax+by=c如果有解的话,c%gcd(a,b)==0;
然后通过拓展欧几里得求出来的x可能小于0,我们要把它转化成整数,代码中要判断一下k是不是大与0,如果小于零的话,取其相反数

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
#define lson l, mid, root << 1
#define rson mid + 1, r, root << 1 | 1
#define father  l , r , root
#define lowbit(x) ( x & ( - x ) )
#define mod 9973
#define ll long long
using namespace std;
const int maxn = 5e5+10;
const int inf = 0x3f3f3f3f;
ll x,y;
ll exgcd(ll a,ll b){
    
    
	if(b==0){
    
    
		x=1;
		y=0; 
		
		return a;
	}
	ll ans=exgcd(b,a%b);
	ll k=x;
	x=y;
	y=k-a/b*y;
	return ans;
}
int main()
{
    
    
	ll xx,yy,m,n,l;
	while(~scanf("%lld%lld%lld%lld%lld",&xx,&yy,&m,&n,&l)){
    
    
		ll g=exgcd(m-n,-l);
		ll c=yy-xx;
		if(c%g==0){
    
    
			ll k=l/g;
			ll ans=x*c/g;
			if(k<0)k=-k;
			ans=(ans%k+k)%k;
			printf("%lld\n",ans);
		}else{
    
    
			printf("Impossible\n");
		}
		
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43715171/article/details/97932135