10407. Простое деление
При делении числа n на d
получается частное q и остаток r. При этом q – максимально
возможное целое, для которого qd £ n, а r = n
– qd. Для любого множества целых чисел {a1, …, ak}
всегда существует такое d, что числа ai mod d
равны.
Вход.
Каждая строка является отдельным тестом и содержит последовательность чисел a1,
…, ak, заканчивающуюся нулем. Последний ноль не принадлежит
самой последовательности. Последовательность содержит не менее 2 и не более
1000 чисел. Не все числа в последовательности равны между собой. Признаком
конца входных данных является строка с одним нулем.
Выход. Для каждой входной
последовательности a1, …, ak найти
максимальное d, для которого при делении ai на d
будут получаться равные остатки.
701 1059 1417 2312 0
14 23 17 32 122 0
14 -22 17 -31 -124 0
0
179
3
3
наибольший общий делитель
Подсказка
1. Рассмотрите второй тест. Чему равны остатки при делении
каждого числа на 3?
2. Рассмотрите третий тест. Чему равны остатки при делении каждого числа на
3? Вспомните, как вычисляются остатки при делении отрицательных чисел на
положительные.
3. Пусть d – максимальное число, для
которого при делении ai на d получаются равные
остатки. Что можно сказать о разности любых двух чисел последовательности по
отношению к d?
4. Представьте числа ai
в виде ai = d * ri + rest и рассмотрите разности ai+1 – ai. Чему равно наибольшее d,
удовлетворяющее выписанным равенствам? Вспомните, что такое наибольший общий делитель.
Из условия задачи следует, что
a1 = d * r1
+ rest
a2 = d * r2
+ rest
…
ak = d * rk
+ rest
Поскольку d максимально ,
то НОД(r1, r2, …, rn) =
1. Далее имеем:
a2 – a1 = d
* (r2 – r1)
a3 – a2 = d
* (r3 – r2)
…
ak – ak-1
= d * (rk – rk-1)
Откуда d = НОД(|a2
– a1|, |a3 – a2|, …, |ak
– ak-1|).
Для первого теста получим:
d = НОД(|1059 – 701|, |1417 –
1059|, |2312 – 1417|) = НОД(358, 358, 895) = 179.
Функция gcd(int
a, int b) вычисляет наибольший общий делитель двух чисел a и b.
int gcd(int
a, int b)
{
return (!b) ?
a : gcd(b, a % b);
}
Основной цикл программы состоит в
чтении последовательности чисел {a1, …, ak}
и последовательном вычислении значения НОД(|a2 – a1|,
|a3 – a2|, …, |ak – ak-1|).
while(scanf("%d
%d",&a,&b),a)
{
res = abs(a - b); a = b;
while(scanf("%d",&b),b)
{
res = gcd(res,abs(a - b));
a = b;
}
printf("%d\n",res);
}