洛谷 P1516 青蛙的约会

https://www.luogu.org/problemnew/show/P1516#sub

 

题意还是非常好理解的.....

假如这不是一道环形的跑道而是一条直线,你会怎样做呢?

如果是我就会列一个方程,像

$$x+m \times k = y+n \times k $$

求出方程解得k值。

然而这是一个环形跑道,也就有了取模的问题,然而我们只需要稍微改变一下方程

$$x + m \times k = y + n \times k + l \times z [z \in \mathbb{Z} ]$$

z表示被%掉了多少圈,我们试着两边转移一下

$$(x-y)+(m-n) \times k = l \times z$$

我们定义$a=(x-y),b=(m-n)$

$$a +b \times k= l \times z $$

$$ bk+lz=a $$

那么我们的任务就变成了解出这个二元一次方程了。

首先判断$ a是否整除gcd(b,l) $,不整除则无解,否则有解的话就可以用扩展欧几里得求得解。

#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
#define LL long long 
LL xx,yy,n,m,x,y,a,b,l,r;
LL gcd(LL a,LL b)
{
    return !b?a:gcd(b,a%b);
}
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    return !b?(x=1,y=0):(exgcd(b,a%b,y,x),y-=a/b*x);
}
int main()
{
    cin>>xx>>yy>>m>>n>>l;
    a=xx-yy;
    b=n-m;
    if(b<0)b=-b,a=-a;
    r=gcd(b,l);
    exgcd(b,l,x,y);
    //现在我们解出的是bx+lz=gcd(b,l)的解,输出答案是要扩大至a. 
    if(a%r!=0)printf("Impossible");
    else  cout<<((x*(a/r))%(l/r)+(l/r))%(l/r);
    //这个答案我研究了好久,最后才发现这个模数是因为组这么多步以后
    //他们两个都回到了起始点. 
//cout<<x*(a/r);
}

 

posted @ 2018-10-10 15:07  Manjusaka丶梦寒  阅读(188)  评论(2编辑  收藏  举报