人生第二道ACM题,我都不知道该说神马了,中文题真不是好惹的,前几天一道递归和数组的中文题就花了我三天,这一题又花了我一个晚上的时间了!
一开始不会做,上网看了解题报告说是数论题。然后就学啊学啊学啊,写完后发现只有21行代码,但花了我一个晚上的时间啊!是题太难还是我太水了?55555~~~
要做此题,先要明白几个定理,为保严谨性我按顺序一一证明出来(心病,不证明的话用得不踏实啊!不然我就不用跑来GDCC了!)
唉,证明太枯燥无味了,先说一下题意吧。
公青蛙一开始在x位置,母青蛙在y位置。公青蛙每次跳m米,母青蛙每次跳n米,并且都是向右跳的。地球经线长度是L,然后地球是圆的,也就是说,跳到L、L+1、L+2……其实就是跳到0、1、2。 公青蛙想追母青蛙,问多少次后它们能跳到一起。如果它们永远不能相遇,就输出Impossible(好可怜啊!)
很明显嘛,就是求一个k,使x + k*m ≡ y + k*n (mod L) 嘛,木有错吧?至少我是这么想滴!然后对方程化简咯,就变成(n-m) * k ≡ x-y (mod L)咯。然后这个方程其实就等价于(n-m)*k + L*s = x-y咯。这就是ax + by = c求整数x的模型。
要求ax + by = c的整数x解,可不是那么简单滴,不然我就不用花了一整个晚上时间了!首先,设d = gcd(a, b),方程两边除以d得到a/d * x + b/d * y = c/d,很显然嘛,a是整除d的,b也是整除d的,而x、y都是整数解,所以要求c/d也是整数嘛。如果c不整除d,当然就是Impossible咯。不然的话,如果我们能求出ax0+by0=d的解x0和y0,那么两边乘以c/d即a(c/d * x0) + b(c/d * y0) = c,就可以得到原来方程的解x = (c/d * x0),y = (c/d * y0)咯。
喂喂喂,等一下,你又怎么知道ax0 + by0 = d一定有解呢?这就得通过严谨的证明了:
定理一:如果d = gcd(a, b),则必能找到正的或负的整数k和l,使d = a*k + b*l。
证明:由于 gcd(a, 0) = a,我们可假设b ≠ 0,这样通过连除我们能够写出
a = b*q1 + r1
b = r1*q2 + r2
r1 &#