Школьный этап, 7–8 классы всероссийской олимпиады по информатике: 6 задач с официальным разбором, к 3 из них наше решение на C++.
К задаче 1Школьный этап ВсОШ по информатике 2026/27, 7–8 классы.
Задачи тура
- 1Разрезание полоскиматематика, жадный алгоритм
- 2Редактирование строкистроки, конструктив
- 3Мобильный интернетматематика, электронные таблицы
- 4Доставка в Простоквашиноматематика, моделирование
- 5Места в автобусематематика, разбор случаев
- 6Кофе помогает от кофематематика, геометрия
Отмечайте решённые: 0 из 6
1. Разрезание полоски
В клетках полоски бумаги записаны цифры:

Полоску разрезали пятью разрезами по клеточкам на шесть частей. Каждая часть состоит из одной или нескольких идущих подряд цифр. Цифры каждой части образуют одно число.
Найдите такое разбиение, чтобы сумма шести получившихся чисел была минимальной. Чем меньше будет сумма чисел в вашем ответе, тем больше баллов вы получите.
Официальный разборСначала попробуйте решить сами
Официальный разбор
Чем короче получившиеся числа, тем меньше их вклад в сумму. При этом порядок цифр менять нельзя: можно только выбирать места разрезов.
Сумма всех цифр полоски равна .
Если объединить две соседние цифры и в двузначное число , то вместо суммы получится число . Сумма увеличится на
Поэтому выгодно объединять соседние цифры, у которых первая цифра как можно меньше.
Всего нужно получить шесть частей из девяти цифр. Если три части будут двузначными, а остальные три — однозначными, то сумма будет минимальной среди разбиений такого вида. В качестве первых цифр двузначных чисел по возможности надо выбрать наименьшие цифры.
Выберем пары 21, 38 и 49. Получим разбиение 5, 21, 38, 7, 49, 6.
Для двузначных чисел мы выбрали в качестве первых цифры 2, 3, 4 с суммой 9. Меньшую сумму получить нельзя, потому что если мы выберем двузначное число 13, то тогда нельзя будет выбрать ни цифру 2, ни цифру 3 первыми цифрами двузначных чисел. Двумя другими минимальными возможными двузначными числами тогда будут числа 52 и 49, а сумма первых цифр двузначных чисел будет равна .
Использовать в ответе трёхзначные и более длинные числа невыгодно, так как число сотен в трёхзначном числе даст дополнительную добавку к общей сумме не менее 90.
Ответ: 5, 21, 38, 7, 49, 6.
2. Редактирование строки
Исполнитель «Редактор» работает со строками, состоящими из букв английского алфавита. У исполнителя есть две команды.
A > B— заменить все буквыAв строке на буквыB;AB > CD— заменить все пары соседних буквABна пары буквCD. Эта команда выполняет замены слева направо, при этом заменённая буква не участвует в последующих заменах этой команды (но может быть заменена следующими командами).
В обозначениях команд буквами A, B, C и D обозначены произвольные буквы английского алфавита. Среди этих букв могут быть совпадающие. Например, если применить команду «AB > BA» к строке «ABBAB», то получится строка «BABBA» (пары символов, где произошли замены, подчёркнуты).
Напишите для исполнителя программу, которая из строки «ABBCBABCBA» получает строку «BCBDBABAAD». Чем меньше операций будет в вашем ответе, тем больше баллов вы получите.
В ответе выпишите операции по одной в строке, каждую в виде A > B или AB > CD. Знак > обязателен, пробелы вокруг него можно не писать.
Официальный разборСначала попробуйте решить сами
Официальный разбор
Будем последовательно преобразовывать исходную строку ABBCBABCBA в строку BCBDBABAAD.
1. Заменим все буквы C на D.
В целевой строке на местах, где в исходной строке стоят буквы C, должны находиться буквы D. Поэтому выполним команду C > D:
ABBCBABCBA — было;
ABBDBABDBA — стало;
BCBDBABAAD — нужно получить.
2. Заменим пары AB на BC.
В начале целевой строки стоят символы BC. В текущей строке в начале строки стоит пара AB. Выполним AB > BC:
ABBDBABDBA — было;
BCBDBBCDBA — стало;
BCBDBABAAD — нужно получить.
Теперь первые пять символов совпадают с целевой строкой. Осталось преобразовать окончание строки.
3. Заменим пары BA на AD.
В конце текущей строки находится пара BA. Заменим её на AD:
BCBDBBCDBA — было;
BCBDBBCDAD — стало;
BCBDBABAAD — нужно получить.
4. Заменим пары CD на BA.
В текущей строке есть пара CD, а в целевой строке на соответствующих позициях должны стоять буквы BA. Выполним CD > BA:
BCBDBBCDAD — было;
BCBDBBBAAD — стало;
BCBDBABAAD — нужно получить.
Теперь в строке осталось исправить одну пару BB: вместо неё должны стоять символы BA.
5. Заменим пары BB на BA.
Выполним команду BB > BA:
BCBDBBBAAD — было;
BCBDBABAAD — стало;
BCBDBABAAD — нужно получить.
Требуемая строка BCBDBABAAD получена за пять операций.
Ответ:
C>D
AB > BC
BA > AD
CD > BA
BB > BA3. Мобильный интернет
Мобильный оператор предлагает тариф, в который каждый месяц включено мегабайт интернета. Тариф стоит рублей.
Если абоненту требуется больше мегабайт, он может покупать дополнительные пакеты. Один пакет содержит 100 мегабайт и стоит рублей. Купить часть пакета нельзя.
Вам известен объём интернет-трафика , израсходованный абонентом за месяц. Сколько рублей ему необходимо заплатить за интернет?
Рассмотрим пример. Если , , , , то за абонентскую плату в 500 рублей пользователь получит 1000 мегабайт, и ему придётся дополнительно приобрести 8 пакетов по 100 мегабайт. Цена одного пакета 50 рублей, и всего пользователь заплатит рублей.
Для выполнения этого задания вам даны 20 наборов значений , , , . Вы должны найти ответ для этих наборов данных. Данные содержатся в файле, который вы можете скачать в формате электронной таблицы Libre Office Calc или Microsoft Excel. В одной строке таблицы записаны значения , , , :
- — количество мегабайт, включённых в тариф;
- — стоимость тарифа в рублях;
- — стоимость одного дополнительного пакета в рублях;
- — объём потреблённого за месяц интернет-трафика в мегабайтах.
Вам необходимо получить ответ для каждого из 20 наборов. Для проведения вычислений вы можете использовать электронные таблицы, языки программирования или другие приложения.
Ответ запишите в виде 20 чисел, каждое в отдельной строке. Если вы не можете дать ответ для какого-либо набора, запишите любое натуральное число. Каждый правильный ответ будет оцениваться в 5 баллов.
Официальный разборСначала попробуйте решить сами
Официальный разбор
Пусть у абонента включено в тариф мегабайт интернета, а стоимость тарифа равна рублей.
Если за месяц использовано не больше мегабайт, достаточно заплатить только рублей.
Если трафик превышает , необходимо приобрести дополнительные пакеты. В каждом пакете 100 мегабайт, поэтому количество пакетов равно разности , делённой на 100 с округлением вверх:
Округление вверх необходимо потому, что купить часть пакета нельзя. Например, если не хватает даже одного мегабайта, всё равно придётся купить целый пакет.
Таким образом, стоимость интернета равна
Нужно вычислить стоимость для 20 заданных наборов , , , . Это можно сделать разными способами: используя электронные таблицы, написав программу или выполняя вычисления на калькуляторе.
Решение в электронных таблицах
Вычислим число дополнительных пакетов как частное от деления превышения трафика над включённым объёмом на 100, округлённое вверх. При этом, если трафик не превышает включённый объём, число пакетов должно быть равно нулю. Поэтому в ячейку E2 можно записать формулу: =B2+ROUNDUP(MAX(0; D2-A2)/100)*C2. Здесь мы вместо разбора случаев и используем функцию MAX(0; D2-A2), которая вернёт значение 0, если после вычитания стандартного месячного пакета трафика получится отрицательное число.
В русскоязычном интерфейсе функции называются ОКРУГЛВВЕРХ и МАКС.
Затем скопируем формулу из E2 в диапазон E2:E21. В этих ячейках появятся ответы для всех 20 наборов данных. Выделим диапазон E2:E21, скопируем его и вставим в поле для ввода ответа.
Решение на языке Python
В Python целое число пакетов можно вычислить с помощью выражения (M-A+99)//100, если . Чтобы не получать отрицательное число пакетов, когда трафика не больше включённого объёма, используем максимум из нуля и разности .
packs = max(0, (M - A + 99) // 100)
print(B + packs * C)В этом коде (M - A + 99) // 100 вычисляет количество пакетов с округлением вверх, когда . После этого к стоимости тарифа прибавляется стоимость всех дополнительных пакетов.
Если нужно обработать все 20 наборов данных одной программой, можно считывать четыре числа для каждого набора и выводить рассчитанную стоимость. Например, полностью программа могла бы выглядеть так:
for i in range(20):
A, B, C, M = map(int, input().split())
packs = max(0, (M - A + 99) // 100)
print(B + packs * C)На вход этой программе можно было бы подать 20 строк по четыре числа в каждой, скопировав из электронной таблицы блок A2:D21.
Ответ на задание
200
320
450
600
1060
2350
5730
11950
33500
82000
133860
246280
636890
1292500
2695770
7945200
25442930
126834150
939658720
9975130004. Доставка в Простоквашино
Недавно почтальон Печкин прочитал в газете о новых роботах-доставщиках и решил использовать одного из них для развоза почты. Он планирует внедрять данную инновацию в деревне Простоквашино, которую можно представить как длинную улицу: в начале — отделение почты, за ним — жилые дома, расположенные в ряд на равном расстоянии друг от друга.
Чтобы проехать от отделения почты до первого дома или от одного дома до соседнего, роботу Печкина требуется единиц энергии. Если робот имеет меньше единиц энергии, он не сможет доехать до следующего дома. При этом предусмотрительный почтальон возле каждого дома разместил зарядную станцию, на которой уровень заряда робота может увеличиться на единиц. Каждой зарядной станцией робот может воспользоваться только один раз.
В качестве «тестового задания» Печкин хочет доставить с помощью робота журнал «Мурзилка» дяде Фёдору, который живет в -м по счёту от почты доме. Теперь ему предстоит выяснить, на какое минимальное число единиц энергии ему необходимо изначально зарядить робота, чтобы тот мог доехать от почты до дома дяди Фёдора.
Формат входных данных
В первой строке входных данных содержится целое число () — количество энергии, необходимое роботу для того, чтобы проехать расстояние между двумя домами.
Во второй строке содержится целое число () — количество энергии, на которое робот может зарядиться у каждого дома.
В третьей строке содержится целое число () — номер (по счёту от здания почты) дома дяди Фёдора.
Гарантируется, что .
Формат выходных данных
Выведите одно число — минимальное количество единиц энергии, на которое Печкину необходимо зарядить робота.
Система оценки
Решения, правильно работающие при , будут оцениваться в 30 баллов.
Решения, правильно работающие при , будут оцениваться в 75 баллов.
Решения, корректно работающие при , будут оцениваться в 35 баллов.
Замечание
В первом примере из условия достаточно зарядить робота на 6 единиц энергии. На дорогу до первого дома он потратит 2 единицы, и у первого дома он зарядится на 1 единицу, у него останется 5 единиц. После зарядки у второго дома останется 4 единицы энергии, у третьего — 3, у четвёртого — 2 и доставщику хватит энергии, чтобы добраться до пятого дома. Можно показать, что меньшего количества энергии роботу не хватит.
| стандартный ввод | стандартный вывод |
|---|---|
2 1 5 | 6 |
| стандартный ввод | стандартный вывод |
|---|---|
2 4 10 | 2 |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
Сначала рассмотрим переборное решение. Будем перебирать возможное начальное количество энергии в переменной ans, начиная с нуля. Для каждого значения проверим, сможет ли робот доехать до дома дяди Фёдора. Для этого будем моделировать его движение: сначала уменьшим запас энергии на , а если он не стал отрицательным, увеличим его на . Если робот смог совершить все поездок между соседними зданиями, то текущее значение ans и будет ответом.
Пример такого решения.
a = int(input())
b = int(input())
k = int(input())
ans = 0
while True:
cc = ans
for i in range(k):
cc -= a
if cc < 0:
break
cc += b
else:
print(ans)
break
ans += 1Это решение перебирает все возможные значения ответа и для каждого из них моделирует движение робота. Если ответ равен , то время работы составляет . В худшем случае это слишком долго, поэтому попробуем улучшить алгоритм.
Заметим, что для проверки начального заряда не обязательно моделировать движение робота отдельно для каждого возможного ответа. Вместо этого можно один раз проследить за изменением его энергии, считая, что изначально она равна нулю. При этом в ходе передвижения робота значение его энергии может стать отрицательным, разрешим роботу передвигаться с отрицательной энергией, запоминая минимальное (отрицательное) значение энергии, которое было у робота в ходе поездки.
Введём переменную cnt, которая будет показывать, как изменился запас энергии относительно начального значения. При каждом перемещении робота на расстояние между соседними зданиями будем уменьшать cnt на , а затем запоминать минимальное значение этой переменной в opt. После этого увеличим cnt на , поскольку робот может воспользоваться зарядной станцией у достигнутого дома.
Начальный заряд должен быть не меньше модуля минимального значения opt. Действительно, если в некоторый момент значение cnt равно , то для сохранения неотрицательного запаса энергии к этому моменту необходимо было изначально иметь не менее единиц энергии.
Пример такого решения.
a = int(input())
b = int(input())
k = int(input())
cnt = 0
opt = 0
for i in range(k):
cnt -= a
opt = min(opt, cnt)
cnt += b
print(-opt)В этом решении каждый шаг моделирования выполняется за , поэтому общая сложность составляет . Такое решение проходит тесты с ограничением , но для полного решения при его недостаточно.
Рассмотрим теперь решение за .
Если , то после подзарядки запас энергии робота увеличивается или остаётся прежним. Поэтому достаточно изначально зарядить робота на единиц энергии: он сможет доехать до первого дома, а затем после каждой подзарядки у него будет достаточно энергии для следующего перемещения. Если , робот может добраться до любого дома без начального заряда, что также соответствует этой формуле.
Теперь рассмотрим случай . После каждого перемещения и последующей подзарядки запас энергии уменьшается на единиц, то есть заряд робота будет уменьшаться при передвижении к последующему дому. Нам нужно так зарядить робота в начале, чтобы он смог доехать до последнего дома, значит, нужно рассмотреть случай, когда робот доезжает до последнего дома с нулевым зарядом. Суммарно на передвижение ему понадобится единиц энергии, но при этом он раз зарядится на единиц энергии. Если его первоначальный заряд был равен , то тогда , откуда .
Итак, ответ можно вычислить по формуле
Пример полного решения.
a = int(input())
b = int(input())
k = int(input())
if b >= a:
print(a)
else:
print(k * a - (k - 1) * b)Это решение использует постоянное число арифметических операций, поэтому его временная сложность составляет , а дополнительная память — . По условию , поэтому вычисления укладываются в заданные ограничения и решение набирает 100 баллов.
Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long a, b, k;
cin >> a >> b >> k;
if (b >= a) {
cout << a << "\n";
} else {
cout << k * a - (k - 1) * b << "\n";
}
return 0;
}5. Места в автобусе
Нумерация мест в автобусе устроена так, как показано на рисунке.

На рисунке изображены первые пять рядов мест. Если в автобусе больше пяти рядов, последующие ряды нумеруются аналогично.
Два друга купили билеты на места с номерами и . Они планируют играть в шахматы во время поездки и хотят определить, насколько удобно им будет играть на этих местах. Они разделили варианты расположения мест на четыре категории.
1. Идеально удобно — друзья сидят рядом, с одной стороны от прохода. Например, места 1 и 2 или 7 и 8.
2. Довольно удобно — друзья сидят в одном ряду, по разные стороны от прохода, оба места находятся у прохода. Например, места 2 и 4.
3. Можно играть — друзья сидят в соседних рядах, с одной и той же стороны от прохода. Например, места 1 и 5 или 4 и 7.
4. Невозможно играть — во всех остальных случаях.
Помогите определить, насколько удобно друзьям играть в шахматы.
Формат входных данных
В первой строке входных данных записано целое число — номер места первого друга.
Во второй строке записано целое число — номер места второго друга.
Числа и различны и удовлетворяют условиям , .
Формат выходных данных
Программа должна вывести одно целое число от 1 до 4 — категорию удобства расположения мест.
| стандартный ввод | стандартный вывод |
|---|---|
1 2 | 1 |
| стандартный ввод | стандартный вывод |
|---|---|
4 2 | 2 |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
В каждом ряду находится четыре места, причём проход разделяет их на две пары. Номера мест в первом ряду — 1, 2, 3, 4, во втором — 5, 6, 7, 8 и так далее. Также заметим, что у прохода находятся места с чётными номерами, а места с нечётными номерами находятся у окна.
Будем считать, что ряды нумеруются с нуля. Тогда номер ряда, в котором находится место с номером , можно вычислить по формуле (x - 1) // 4, где // — целочисленное деление. Аналогично вычислим номер ряда для места .
В начале выполнения программы удобно сделать так, чтобы . Если изначально , поменяем значения переменных местами.
Теперь рассмотрим все четыре категории расположения мест.
1. Идеально удобно.
В этом случае друзья сидят рядом, с одной стороны от прохода. Такие места имеют номера 1 и 2, 5 и 6, 9 и 10 и так далее либо 3 и 4, 7 и 8, 11 и 12 и так далее.
Поскольку , для первой пары мест в ряду номер должен быть нечётным, а номер должен равняться . Кроме того, оба места должны находиться в одном ряду.
2. Довольно удобно.
В этом случае друзья сидят в одном ряду по разные стороны от прохода, причём оба места находятся у прохода. У прохода находятся места с чётными номерами, поэтому оба значения и должны быть чётными, а также места должны находиться в одном ряду.
3. Можно играть.
В этом случае друзья сидят на соседних рядах с одной и той же стороны от прохода. Например, места 1 и 5, а также места 4 и 8.
В этом случае нам неважно, находятся ли места у прохода или у окна, они только должны находиться в соседних рядах и по одну сторону от прохода. Рассмотрим места с номерами x + x % 2 и y + y % 2, где % — операция взятия остатка от деления. В результате преобразования нечётный номер места сменится на номер соседнего с ним места у прохода. То есть места x + x % 2 и y + y % 2 будут находиться оба у прохода, и они будут либо совпадать с местами и , либо будут соседними с ними.
Два места у прохода будут находиться друг за другом (то есть в соседних рядах по одну сторону от прохода), если их номера отличаются на 4. То есть в третьем случае нужно проверить условие x + x % 2 + 4 == y + y % 2.
Если ни одно из перечисленных условий не выполняется, расположение мест относится к четвёртой категории.
Полное решение выглядит следующим образом.
x = int(input())
y = int(input())
if x > y:
x, y = y, x
row1 = (x - 1) // 4
row2 = (y - 1) // 4
if row1 == row2 and x % 2 == 1 and y == x + 1:
print(1)
elif row1 == row2 and x % 2 == 0 and y % 2 == 0:
print(2)
elif x + x % 2 + 4 == y + y % 2:
print(3)
else:
print(4)Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long x, y;
cin >> x >> y;
if (x > y) swap(x, y);
long long row1 = (x - 1) / 4;
long long row2 = (y - 1) / 4;
if (row1 == row2 && x % 2 == 1 && y == x + 1) {
cout << 1 << "\n";
} else if (row1 == row2 && x % 2 == 0 && y % 2 == 0) {
cout << 2 << "\n";
} else if (x + x % 2 + 4 == y + y % 2) {
cout << 3 << "\n";
} else {
cout << 4 << "\n";
}
return 0;
}6. Кофе помогает от кофе
Миша — прилежный ученик и очень любит ходить в школу, а после школы, как уважающий себя программист, любит заходить за кофе. Однажды Миша выпил слишком много кофе и совершенно забыл, где находится его школа. В блокноте у Миши записаны координаты его дома . Кофейня находится в точке . Школа, дом и кофейня находятся в точках с целыми координатами, при этом координаты могут совпадать.
У Миши есть шагомер, который показывает, что сегодня он прошёл ровно шагов. За один шаг Миша проходит расстояние, равное 1; он может двигаться только параллельно осям координат.
Миша уверен, что утром он прошёл кратчайшим путём от дома до школы, а после школы — кратчайшим путём от школы до кофейни.
Помогите Мише найти хотя бы одну возможную позицию школы или сообщите, что Миша где-то ошибся и не существует такой позиции школы, при которой он мог бы пройти ровно шагов.
Формат входных данных
В первых двух строках входных данных записаны координаты дома Миши: в первой строке — число , во второй строке — число .
В следующих двух строках записаны координаты кофейни: в третьей строке — число , в четвёртой строке — число .
В пятой строке содержится целое число () — количество шагов, пройденных Мишей от дома до кофейни.
Все числа — целые, неотрицательные и не превосходят .
Формат выходных данных
Программа должна вывести два целых числа — координаты школы Миши. Значения координат по модулю не должны превосходить . Если есть несколько возможных расположений школы, нужно вывести любое из них. Если подходящей точки для школы не существует, программа должна вывести число .
Система оценки
Решения, правильно работающие, когда все числа во входных данных не превосходят 500, будут оцениваться в 30 баллов.
Решения, правильно работающие, когда , будут оцениваться в 50 баллов.
Замечание
Иллюстрация к первому примеру из условия.

| стандартный ввод | стандартный вывод |
|---|---|
0 0 2 2 6 | -1 0 |
| стандартный ввод | стандартный вывод |
|---|---|
1 7 9 0 10 | -1 |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
Обозначим координаты дома через , а координаты кофейни — через . Требуется найти целочисленные координаты школы , для которых сумма манхэттенских расстояний от дома до школы и от школы до кофейни равна :
Если такой точки не существует, необходимо вывести .
Для небольших ограничений можно перебрать возможные координаты школы. Если все входные числа не превосходят 500, достаточно рассмотреть координаты и от до включительно.
Действительно, расстояние от дома до школы не может превышать , поскольку оно является частью суммы, равной . Поэтому координаты школы отличаются от координат дома не более чем на . С учётом ограничений на входные данные обе координаты школы лежат в указанном диапазоне.
Переберём все точки в этом диапазоне. Для каждой точки вычислим сумму расстояний до дома и кофейни. Если она равна , выведем координаты найденной точки и завершим программу. Если перебор закончится без результата, выведем .
import sys
x1 = int(input())
y1 = int(input())
x2 = int(input())
y2 = int(input())
d = int(input())
for x in range(-500, 1001):
for y in range(-500, 1001):
dist = abs(x - x1) + abs(y - y1) + abs(x - x2) + abs(y - y2)
if dist == d:
print(x, y)
sys.exit()
print(-1)Перебирается точек. Сложность решения составляет , где — количество возможных значений каждой координаты.
Можно улучшить перебор, выбрав диапазоны координат в зависимости от входных данных.
Поскольку каждое из четырёх слагаемых в условии неотрицательно, каждое из них не превосходит . В частности, и .
Следовательно, координата должна находиться в диапазоне . Аналогично, для координаты получаем диапазон .
Переберём все точки в этих диапазонах и проверим условие задачи. Как только найдём подходящую точку, выведем её координаты и завершим программу. Если ни одна точка не подойдёт, выведем .
import sys
x1 = int(input())
y1 = int(input())
x2 = int(input())
y2 = int(input())
d = int(input())
for x in range(max(x1, x2) - d, min(x1, x2) + d + 1):
for y in range(max(y1, y2) - d, min(y1, y2) + d + 1):
dist = abs(x - x1) + abs(x - x2) + abs(y - y1) + abs(y - y2)
if dist == d:
print(x, y)
sys.exit()
print(-1)Сложность решения составляет . Такой подход позволяет обрабатывать более крупные значения входных данных, однако при больших ограничениях перебор всё ещё может оказаться слишком медленным.
Решение на 100 баллов. Рассмотрим расстояние между домом и кофейней:
По неравенству треугольника сумма расстояний от дома до школы и от школы до кофейни не может быть меньше расстояния между домом и кофейней. Поэтому необходимо, чтобы .
Есть и второе необходимое условие: числа и должны иметь одинаковую чётность. Действительно, при каждом шаге по горизонтали или вертикали чётность суммы координат меняется. Поэтому чётность длины любого пути между двумя фиксированными точками определяется этими точками. В частности, .
Если хотя бы одно из двух условий не выполняется, то ответа не существует, и нужно вывести .
Докажем, что при выполнении этих условий ответ всегда существует.
Выберем из дома и кофейни точку с меньшей координатой . Обозначим её координаты через . Если , то , иначе .
Если разместить школу в этой точке, сумма расстояний от неё до дома и кофейни будет равна . Теперь переместим школу влево на клеток. Это целое неотрицательное число, поскольку и числа и имеют одинаковую чётность.
Так как не превосходит обеих исходных координат и , перемещение влево на клеток увеличит расстояние до каждой из двух точек ровно на . Координата при этом не изменится. Следовательно, сумма расстояний увеличится на и станет равна .
Таким образом, при выполнении необходимых условий подходящую точку можно построить непосредственно.
x1 = int(input())
y1 = int(input())
x2 = int(input())
y2 = int(input())
d = int(input())
dist = abs(x1 - x2) + abs(y1 - y2)
if d < dist or d % 2 != dist % 2:
print(-1)
else:
if x1 <= x2:
x0, y0 = x1, y1
else:
x0, y0 = x2, y2
x0 -= (d - dist) // 2
print(x0, y0)Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long x1, y1, x2, y2, d;
cin >> x1 >> y1 >> x2 >> y2 >> d;
long long dist = llabs(x1 - x2) + llabs(y1 - y2);
if (d < dist || d % 2 != dist % 2) {
cout << -1 << "\n";
return 0;
}
long long x0 = x1, y0 = y1;
if (x2 < x1) {
x0 = x2;
y0 = y2;
}
x0 -= (d - dist) / 2;
cout << x0 << " " << y0 << "\n";
return 0;
}Сначала решите сами
Возьмите столько времени, сколько было на олимпиаде, и только потом открывайте разбор.
Другие туры
2026/27
- Школьный этап, 9–11 классы5 задач
- Школьный этап, 7–8 классы6 задач
- Школьный этап, 5–6 классы5 задач
2025/26
- Школьный этап, 9–11 классы5 задач
- Школьный этап, 7–8 классы6 задач
- Школьный этап, 5–6 классы5 задач
- Муниципальный этап, 9–11 классы5 задач
- Муниципальный этап, 7–8 классы6 задач
2024/25
- Школьный этап, 9–11 классы5 задач
- Школьный этап, 7–8 классы7 задач
- Школьный этап, 5–6 классы5 задач
- Муниципальный этап, 9–11 классы5 задач
- Муниципальный этап, 7–8 классы7 задач
2023/24
- Школьный этап, 9–11 классы5 задач
- Школьный этап, 7–8 классы7 задач
- Школьный этап, 5–6 классы5 задач
- Муниципальный этап, 9–11 классы5 задач
- Муниципальный этап, 7–8 классы7 задач