When performing integer
division of a dividend n by a divisor
d, we obtain a quotient q and a remainder r. The quotient q is the
largest integer for which the inequality q
· d ≤ n holds, and the remainder is given by r = n – q·d.
It is known that for any
set of integers, there exists an integer d
such that dividing each of these numbers by d
yields the same remainder.
Input. Each line contains a sequence of 32-bit integers. The
last number in each line is 0 and does not belong to the sequence. Each
sequence contains at least 2 and at most 1000 numbers. It is guaranteed that
not all numbers in a sequence are equal. The last line contains a single 0 and
should not be processed.
Output. For each line, print the
largest integer d such that dividing
each number in the given sequence by d
yields the same remainder.
|
Sample
input |
Sample
output |
|
701 1059 1417 2312 0 14 23 17 32 122 0 14 -22 17 -31 -124 0 0 |
1793
3 |
the greatest common divisor
Hint
1. Consider the second test
case. What are the remainders when each number is divided by 3?
2. Consider the third test
case. What are the remainders when each number is divided by 3? Recall how
remainders are computed for negative numbers divided by positive numbers.
3. Let d be the largest number such that dividing all numbers ai by d gives the same remainder.
What can be said about the difference between any two numbers in the sequence
with respect to d?
4. Represent the numbers ai as ai = d * ri + rest and consider the differences ai+1 – ai. What is the largest possible value of
d that satisfies these
equalities? Recall the definition of the greatest common divisor.
Let a sequence of numbers
be given: a1, a2, …, ak.
If, when dividing each
number ai (1 ≤ i
≤ k) by d, the remainder is the same, denote this remainder
as rest. Then each number can be written in the form:
a1 = d * r1
+ rest
a2 = d * r2
+ rest
…
ak = d * rk
+ rest
Here r₁, r₂,
…, rₖ are integers (the quotients of the divisions).
Now, subtract the
consecutive elements of the sequence:
a2 – a1
= d * (r2 – r1)
a3 – a2
= d * (r3 – r2)
…
ak – ak-1
= d * (rk – rk-1)
In all these differences,
the number d is a factor. This means that d divides each of the
differences: a2 – a1, a3 – a2,
…, ak – ak-1.
We are looking for the
largest possible d that divides all these differences. By definition, the
largest number that divides several numbers simultaneously is their greatest
common divisor (GCD). Therefore
d = GCD(|a2
– a1|, |a3 – a2|, …, |ak
– ak-1|)
Since d is chosen
to be maximal, the numbers r₂ − r₁, r₃
− r₂, … have no common divisor greater than 1. Otherwise,
this common divisor could be factored out, increasing d, which would
contradict its maximality. Therefore
GCD (r1,
r2, …, rn) = 1
Also note that if, for
example, from each equation of the form ai = d * ri + rest (2 ≤ i
≤ k) we subtract the first one, then the answer can be written as:
d = GCD (|a2
– a1|, |a3 – a1|, …, |ak
– a1|)
Sometimes, computations in
this form are more convenient.
Example
For the first test case we
have:
d = GCD(|1059 – 701|, |1417
– 1059|, |2312 – 1417|) = GCD(358, 358, 895) = 179
Algorithm implementation
The function gcd computes the greatest common
divisor of two numbers a and b.
int gcd(int
a, int b)
{
return (!b) ?
a : gcd(b, a % b);
}
The main part of the
program. Read the first number a1. If it is 0, this means it is the
last line and should not be processed – we exit the loop.
while (scanf("%d", &a), a)
{
The variable res
stores the current result – the greatest common divisor of the differences.
res = 0;
Read the next number of
the line into the variable b. The result is computed using the formula
d = GCD(|a2
– a1|, |a3 – a1|, …, |ak
– a1|)
In the code, the variable a
stores the value of a1, while the variable b takes the values a2, a3, …,
ak.
while (scanf("%d", &b), b)
res = gcd(res, abs(b - a));
Print the answer.
printf("%d\n", res);
}
Java implementation
import java.util.*;
public class Main
{
static int gcd(int a, int b)
{
return (b == 0) ? a : gcd(b, a % b);
}
public static void main(String []args)
{
Scanner con = new Scanner(System.in);
while(true)
{
int a = con.nextInt();
if (a == 0) break;
int b = con.nextInt();
int res = Math.abs(a - b);
a = b;
while(true)
{
b = con.nextInt();
if (b == 0) break;
res = gcd(res,Math.abs(a-b));
a = b;
}
System.out.println(res);
}
con.close();
}
}