洛谷 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#include #include 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< }