Class: number theory, Extended Euclidean algorithm, same equation Author: acshiryu time: 2011-8-3 original question: http://poj.org/problem? Id = 1061 frog appointment
Time limit:1000 ms |
|
Memory limit:10000 K |
Total submissions:62869 |
|
Accepted:9818 |
Description
The two frogs met each other on the Internet. They had a good chat, so they thought it was necessary to meet each other. They are happy to find that they live on the same latitude line, so they agreed to jump westward until they met each other. However, before they set out, they forgot a very important thing. They did not know the characteristics of the other party, nor agreed on the specific location of the meeting. However, frogs are optimistic. They think that as long as they keep jumping in a certain direction, they will always meet each other. However, unless the two frogs jump to the same point at the same time, they will never be able to meet each other. To help the two optimistic frogs, you are asked to write a program to determine whether the two frogs can meet and when.
The two frogs are called Frog A and frog B respectively, and The 0th degree of the latitude line is the origin, from East to West is the positive direction, the unit length is 1 meters, in this way, we get a number axis that is connected at the beginning and end. Set the starting coordinate of frog a to X, and that of frog B to y. Frog A can jump M meters at a time, and frog B can jump n meters at a time. It takes the same time for the two frogs to jump at a time. The total length of the latitude line is l meters. Now you need to find out how many times they will be met.
Input
The input contains only five integers x, y, M, N, and l in a row. x = Y <2000000000,0 <m, n <2000000000,0 <L <2100000000.
Output
Outputs the number of jumps required for the meeting. If the meeting is never possible, an "impossible" line is output"
Sample Input
1 2 3 4 5
Sample output
4
For the data in the question, see the table below
Therefore, you can get two frogs to jump four times to meet each other.
We can know that when they encounter the problem, the displacement from the origin point is equal. If the frog jumps t times, their displacement relative to the origin point is
A :( x + MT) % L
B :( y + nt) % L
Then you can column the equation (x + MT)-(Y + nt) = Cl (C is an integer)
(M-N) T-Cl = Y-X;
The question requires a positive integer t at the hour when the equation is created.
Before solving this problem, we should first know what the Extended Euclidean algorithm is.
That is
Returns an integer (x, y) so that ax + by = gcd (A, B ).
Note: Here, X and Y are not necessarily positive numbers, or negative or 0.
The following is the source program for extending the Euclidean Algorithm: (refer to Liu rujia's "algorithm competition getting started classic" Page 179th)
1 void gcd (int A, int B, Int & D, Int & X, Int & Y)
2 {// A and B represent the coefficients of the equation, respectively. d returns the maximum common divisor of A and B, and X and Y returns the corresponding solution.
3 if (! B) // when B is equal to 0, the equation is changed to AX = gcd (A, 0) = A. Therefore, we can obviously obtain the solution of the equation as x = 1, y = 0, and D is
4 d = A, x = 1, y = 0;
5 else
6 {// recursively calculate the solution of the equation, which is proved below
7 gcd (B, A % B, D, Y, X );
8 y-= (a/B) * X;
9}
10}
This algorithm is not proved in the book. It is only replaced by "mathematical induction is not difficult to prove the correctness of the algorithm". Now, let's prove the correctness of this algorithm.
It is easy to understand when B = 0. For more information, see the notes above.
The key is that when B =/= 0, we first assume that a positive integer of the equation AX + by = gcd (a, B) = D is resolved as X1, Y1; do not doubt, this equation must be resolved.
Then ax1 + by1 = gcd (A, B) (1)
For equation bx + (a mod B) y = gcd (B, A mod B), there is a solution X2, Y2 (hypothesis)
Bx2 + (a mod B) y2 = gcd (B, A mod B) = gcd (A, B) (2)
And a mod B = A-(A/B) * B;
Then the formula (2) is changed to bx2 + (a-(A/B) * B) y2 = gcd (A, B );
That is, ay2 + B (x2-(A/B) * Y2) = gcd (a, B) (3 );
Comparison (1) (3)
X1 = Y2; Y1 = x2-(A/B) * Y2
Therefore, the solution of AX + by = gcd (a, B) only needs to be in the equation bx + (a mod B) y = gcd (B, A mod B) after a simple operation is performed on the basis of the solution, it becomes the solution of the original equation. Because GCD is continuously recursive When B = 0, the solution of the equation can be obtained through recursion.
Then we obtain the solutions of the equation AX + by = gcd (a, B) x0, y0,
However, how can I solve the problem;
Assume that the equation is AX + by = C;
Now we know the solutions x0 and Y0 for AX + by = gcd (a, B), that is, ax0 + by0 = gcd (A, B );
Then the two sides of the equation are multiplied by C/gcd (A, B ).
Ax0 * C/gcd (a, B) + by0 * C/gcd (a, B) = C; (if C is not a gcd (A, B))
Therefore, one solution of the original equation is X1 = x0 * C/gcd (a, B), Y1 = y0 * C/gcd (A, B ),
Based on the following conclusions, we can draw a good answer to this question.
Set A, B, and C to any integer. If a group of integers in the equation AX + by = C is interpreted as (x0, y0), any integer solution of it can be written as (x0 + kb ', y0-ka '), where a' = A/gcd (a, B), B '= B/gcd (a, B), k is any integer
The conclusion above proves that it is omitted here.
At the beginning, I didn't notice how to answer the question. Wa twice.
Reference code:
1 # include <iostream>
2 # include <cstdlib>
3 # include <cstdio>
4 # include <cstring>
5 # include <algorithm>
6 # include <cmath>
7 using namespace STD;
8
9 void gcd (_ int64 A, _ int64 B, _ int64 & D, _ int64 & X, _ int64 & Y)
10 {
11
12 if (! B)
13 d = A, x = 1, y = 0;
14 else
15 gcd (B, A % B, D, Y, x), Y-= x * (A/B );
16}
17
18 int main ()
19 {
20 _ int64 S, T, m, n, l;
21 While (~ Scanf ("% i64d % i64d % i64d % i64d % i64d", & S, & T, & M, & N, & L ))
22 {
23 _ int64 A, B, D, ans;
24 _ int64 X, Y;
25 A = L;
26 B = m-N;
27 ans = t-s;
28 If (B <0)
29 B = N-M, ANS = s-t;
30 gcd (A, B, D, x, y );
31 if (ANS % d) // no solution
32 printf ("impossible \ n ");
33 else
34 {
35 _ int64 TMP = L/d;
36 ans = (ANS/D * Y) % TMP; // obtain the answer. Because the answer has the minimum requirement, the remainder must be obtained for the "Cycle" of the answer.
37 If (ANS <0) // if a negative number is displayed, the cycle is added.
38 ans + = TMP;
39 printf ("% i64d \ n", ANS );
40}
41}
42 return 0;
43}