Школьный этап, 7–8 классы всероссийской олимпиады по информатике: 7 задач с официальным разбором, к 3 из них наше решение на C++.
К задаче 1Школьный этап ВсОШ по информатике 2023/24, 7–8 классы.
Задачи тура
- 1Защитный экранперебор, математика
- 2Гоночная трассамоделирование, поиск в ширину
- 3Бег по пересечённой местностиграфы, конструктив
- 4Конференцияжадный алгоритм, электронные таблицы
- 5Пара-тройка конфетматематика
- 6Речной бойматематика
- 7Сломанный индикатормножества, реализация
Отмечайте решённые: 0 из 7
1. Защитный экран
В радиологической лаборатории во время экспериментов используются защитные свинцовые экраны. В зависимости от расстояния, на которое излучение может проникнуть в материал (проникающей способности), подбирается экран из одной или нескольких свинцовых пластин толщиной от 1 до 100 сантиметров.
В лаборатории есть семь пластин толщиной 32, 3, 37, 8, 2, 17, 1 сантиметров. В сумме они дают ровно 100 сантиметров. Сотрудники планируют провести эксперимент с новым видом излучения, проникающая способность которого неизвестна, то есть им необходимо собрать из имеющихся пластин экран некоторой толщины от 1 до 100 сантиметров.
Определите все возможные значения проникающей способности излучения, для которых не удастся собрать защитный экран нужной толщины, используя имеющиеся в лаборатории пластины. Каждое значение записывайте в отдельное поле, добавляя их по мере необходимости. В ответе укажите несколько чисел (единицу измерения указывать не нужно), добавляя поля ввода по мере необходимости.
Официальный разборСначала попробуйте решить сами
Официальный разбор
Прежде всего необходимо упорядочить данные числа, получим 1, 2, 3, 8, 17, 32, 37.
Используя пластины 1, 2, 3, можно собрать экран любой толщины от 1 до 6. Экран толщины 7 собрать не получится, а используя пластину 8 и меньшие пластины, можно собрать экраны толщины от 8 до 14. Так как следующая пластина имеет толщину 17, экраны толщиной 15 и 16 собрать не получится, а используя пластину 17 и меньшие пластины, можно собрать экраны толщиной от 17 до , кроме .
Теперь рассмотрим пластину 32. Вместе с меньшими пластинами с её помощью можно собрать все экраны от 32 до , кроме , , и . Итого, при использовании пластин 1, 2, 3, 8, 17, 32 «невозможными» будут комбинации 7, 15, 16, 24, 39, 47, 48, 56.
Теперь рассмотрим пластину 37. С её помощью можно собрать экраны толщиной от 37 до , кроме , , , , , , и . При этом заметим, что мы смогли получить экраны толщиной 39, 47, 48, 56, которые раньше считались невозможными, а экраны толщиной 44, 52, 53, 61, которые мы смогли получить раньше, всё так же возможны.
Ответ: 7, 15, 16, 24, 76, 84, 85, 93.
2. Гоночная трасса
Гоночная трасса имеет форму, изображённую на рисунке.

Гоночный автомобиль выезжает из левого верхнего угла трассы и за первую минуту перемещается на 1 клетку вправо. Далее за каждую последующую минуту автомобиль перемещается на целое число клеток по прямой в одном направлении. Каждую минуту автомобиль может изменять скорость не более чем на 1, то есть за каждую минуту автомобиль проезжает столько же клеток, сколько за предыдущую минуту, или на одну клетку больше или на одну клетку меньше. Поскольку каждое перемещение выполняется по прямой, в тех клетках, в которых происходит поворот трассы, должно закончиться очередное перемещение автомобиля.
Постройте алгоритм прохождения автомобилем трассы за минимальное время. Автомобилю необходимо завершить свой маршрут также в левом верхнем углу трассы, при этом последнее перемещение требуется осуществить на 1 клетку, чтобы автомобиль остановился в конечной клетке трассы.
В ответе запишите последовательность чисел, соответствующую перемещению автомобиля каждую минуту. Каждые два соседних числа в последовательности должны отличаться не более, чем на 1, первое и последнее число должны быть равны 1. Каждое значение записывайте в отдельное поле, добавляя их по мере необходимости. Чем меньше чисел будет в вашем ответе, тем больше баллов вы получите (при условии, что последовательность перемещений будет удовлетворять всем необходимым условиям).
Например, если трасса имела бы такой вид, как на рисунке справа, то в ответе необходимо записать числа 1, 2, 2, 2, 1, 1, 1. На рисунке эти числа записаны в конечных клетках соответствующего перемещения.

Официальный разборСначала попробуйте решить сами
Официальный разбор
Самый быстрый способ прохождения трассы изображён на рисунке.

В ответе нужно записать числа 1, 2, 2, 2, 3, 3, 4, 3, 2, 3, 4, 3, 2, 1, 1.
3. Бег по пересечённой местности
Участникам соревнования по бегу по пересечённой местности необходимо преодолеть маршрут из левого верхнего угла в правый нижний угол участка, состоящего из клеток. Участник может перемещаться из клетки в одну из четырёх клеток, имеющих общую сторону с клеткой, где он находится в данный момент, не выходя при этом за границу квадрата. На рисунке изображён вид участка и один из возможных маршрутов бегуна. Участники всегда выбирают кратчайший маршрут.

Организаторы соревнований хотят удлинить маршрут спортсменов, для этого они планируют перекрыть некоторые клетки препятствиями, чтобы они стали недоступны для участников. Организаторы хотят разместить препятствия так, чтобы кратчайший маршрут от старта до финиша стал как можно длиннее. Также они хотят использовать минимально возможное число препятствий.
В ответе запишите 8 строк по 8 символов «.» и «#», где символ «.» означает пустую клетку, а символ «#» — клетку с препятствием. Левый верхний и правый нижний углы вашего ответа должны быть свободными, также должен существовать маршрут из левого верхнего в правый нижний угол.
Чем длиннее будет кратчайший путь от старта до финиша в вашем ответе, тем больше баллов вы получите. При одинаковой длине кратчайшего пути больше баллов получит ответ, содержащий меньшее число препятствий. При этом, независимо от количества препятствий, решение с большей длиной пути получит больше баллов, чем с меньшей.
Официальный разборСначала попробуйте решить сами
Официальный разбор
Довольно несложно построить путь из 35 клеток, используя 19 блоков. Такое решение получит 70 баллов.

Но это решение можно улучшить, добавив дополнительные изгибы в тех местах, где происходит движение по прямой. Построим путь из 39 клеток, используя 19 блоков:

4. Конференция
Для выступления на очень важной конференции подали заявки 1000 докладчиков. Каждый из них готов сделать доклад строго в указанное время, но одновременно может выступать только один докладчик, поэтому удовлетворить все заявки невозможно.
Выберите наибольшее число докладчиков так, чтобы указанные ими времена выступления не пересекались. В один момент времени может завершиться один доклад и начаться другой.
Данные для выполнения этого задания находятся в файле электронной таблицы.
Вы можете скачать файл в одном из двух форматов: Microsoft Excel (XLSX) или LibreOffice Calc (ODS).
Файл содержит три колонки. В колонке A указан номер докладчика от 1 до 1000, в колонках B и C указаны желаемые времена начала и окончания доклада в формате времени электронной таблицы. Количество секунд во всех временах равно нулю.
В ответ запишите номера докладчиков (числа от 1 до 1000), которых вы выберете для выступления на конференции. Каждое число записывайте в отдельное поле ввода, добавляя поля по мере необходимости. Времена выступлений выбранных докладчиков не должны пересекаться. Чем больше докладов вы выберете, тем больше баллов получите (при условии, что предложенный вами набор докладчиков удовлетворяет условию задачи).
Для выполнения задания вы можете использовать электронные таблицы из офисного пакета или любые другие средства вашего компьютера.
Официальный разборСначала попробуйте решить сами
Официальный разбор
Задача решается про помощи «жадного алгоритма». Выберем докладчика, которых хочет закончить свой доклад раньше всех. Вторым выберем докладчика, который готов закончить раньше всех из тех докладчиков, которые выступают после первого. Затем выберем докладчика, который заканчивает раньше всех из тех, кто начинает после второго выбранного и т.д.
Для реализации этого решения отсортируем входные данные по столбцу C, то есть по времени окончания доклада. Теперь в ячейку D2 запишем формулу =IF(B2>=MAX($D$1:D1);C2;""). Эта формула запишет в ячейку время окончания выступления этого докладчика (C2), если время начала его выступления (B2) не меньше, чем максимальное время выступления ранее выбранных докладчиков (формула с функцией MAX), иначе это будет пустая строка. Затем эту формулу скопируем в ячейки D3:D1001. Тем самым для докладчиков, которых мы выберем, в столбце D будет записано время окончания их выступления, а для остальных докладчиков — пустая строка.
Осталось только при помощи фильтра выбрать строки с непустыми значениями в столбце D и взять из столбца A номера выбранных докладчиков.
Ответ: 249, 296, 468, 512, 523, 640, 777, 799, 804, 819, 855, 876, 915. Возможны и другие варианты ответа, в лучшем решении выбраны 13 докладчиков.
5. Пара-тройка конфет
У Алисы сегодня день рождения, и она хочет угостить своих одноклассников конфетами. В магазине, в который она успеет зайти перед школой, есть сладости двух видов: шоколадные и карамельные. Они продаются наборами по 3 штуки, причем в упаковке есть конфеты каждого из двух видов (то есть в одной упаковке лежат две конфеты одного вида и одна конфета другого вида). По внешнему виду упаковки нельзя понять, какие конфеты лежат внутри.
Чтобы никого не обидеть, всем в классе нужно раздать конфеты одного вида, а оставшиеся девочка заберёт домой. Алисе нужно собираться в школу, поэтому она попросила вас посчитать, какое минимальное число упаковок нужно купить, чтобы конфет хватило на всех.
Формат входных данных
В единственной строке задано число () — количество человек в классе.
Формат выходных данных
Выведите единственное число — количество упаковок, которое должна купить Алиса.
Система оценки
Решения, правильно работающие при , будут оцениваться в 25 баллов.
Решения, правильно работающие при , будут оцениваться в 50 баллов.
Замечание
В первом примере Алиса купит две упаковки с конфетами. В первой упаковке лежат 2 конфеты одного вида, и 1 конфета другого вида. Если вторая упаковка будет такая же, как и первая, то у Алисы окажется 4 конфеты одного вида и 2 конфеты другого вида. Если вторая упаковка будет отличаться от первой, то у Алисы будет по 3 конфеты каждого вида. В любом случае у Алисы найдётся 3 конфеты одного вида.
Как видно из первого примера, для того, чтобы гарантированно получить 4 конфеты одного вида, недостаточно купить две упаковки.
| стандартный ввод | стандартный вывод |
|---|---|
3 | 2 |
| стандартный ввод | стандартный вывод |
|---|---|
4 | 3 |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
Заметим, что упаковки конфет могут быть двух типов: с двумя шоколадными + одной карамельной или одной шоколадной + двумя карамельными. Также заметим, что ответ не превосходит , так как в каждой упаковке есть хотя бы одна конфета каждого вида.
При можно перебрать количество купленных коробок и убедиться, что при любом распределении конфет в купленных упаковках найдётся не менее конфет одного вида.
Пусть — количество купленных коробок, из них — первого типа (две шоколадные и одна карамельная), тогда — число коробок второго типа (одна шоколадная и две карамельные). Конфет одного вида будет . Для выбранного переберём значения такие, что и если для всех верно, что , то данное значение подходит. Минимальное подходящее является ответом.
Такое решение имеет сложность и набирает 25 баллов. Пример такого решения.
n = int(input())
k = 1
ok = False
while not ok:
ok = True
for k1 in range(k + 1):
k2 = k - k1
if max(2 * k1 + k2, k1 + 2 * k2) < n:
ok = False
k += 1
print(k - 1)При всё ещё получится перебирать значения , но необходимо избавиться от вложенного цикла, перебирающего возможное распределение упаковок. Заметим, что в худшем случае (чтобы минимизировать количество конфет одного вида), значение , то есть конфет каждого вида окажется примерно поровну.
Заметим, что в двух упаковках точно найдётся три конфеты одного вида. Если мы покупаем чётное число упаковок, то среди них точно будет конфет одного вида. Если нечетное, то количество конфет одного вида будет не меньше, чем . Переберём значения , пока не найдём минимальное подходящее.
Такое решение имеет сложность и набирает 50 баллов. Пример такого решения.
n = int(input())
k = 0
while k // 2 * 3 + (k % 2) * 2 < n:
k += 1
print(k)Полное решение имеет сложность . Если делится на 3, то нужно купить упаковок (в каждых двух упаковках есть три конфеты одного вида). Если же купить на одну упаковку больше, то в лишней упаковке окажутся 2 одинаковые конфеты. Поэтому для тех значений , которые не делятся на 3, нужно будет купить ещё одну дополнительную упаковку.
Пример такого решения.
n = int(input())
if n % 3 == 0:
print(n // 3 * 2)
else:
print(n // 3 * 2 + 1)Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long n;
cin >> n;
long long answer = n / 3 * 2;
if (n % 3 != 0) answer += 1;
cout << answer << "\n";
return 0;
}6. Речной бой
Поле в игре «Речной бой» представляет собой полоску длины клеток и шириной в одну клетку. Где-то на поле расположен корабль из клеток (). Какое наименьшее число выстрелов необходимо, чтобы гарантированно потопить корабль? После каждого выстрела сообщается его результат: «мимо», «ранен» или «убит».
Формат входных данных
Первая строка входных данных содержит целое число ().
Вторая строка входных данных содержит целое число ().
Формат выходных данных
Выведите одно целое число — количество выстрелов.
Система оценки
Решения, правильно работающие при , будут оцениваться в 40 баллов.
Замечание
В первом примере поле состоит из клеток, корабль имеет длину . Первый выстрел нужно сделать в одну из двух центральных клеток. Если результатом будет «ранен», то вторая клетка корабля находится в одной из двух соседних клеток, и за два выстрела мы гарантированно потопим корабль Если результатом первого выстрела будет «мимо», то корабль занимает две единственные свободные смежные клетки, которые тоже можно подбить двумя выстрелами. Итого нужно 3 выстрела. Двух выстрелов недостаточно, так как всегда есть шанс промахнуться первым выстрелом.
| стандартный ввод | стандартный вывод |
|---|---|
4 2 | 3 |
| стандартный ввод | стандартный вывод |
|---|---|
4 4 | 4 |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
Будем стрелять последовательно так, чтобы не пропустить корабль. Для этого нужно стрелять, оставляя между выстрелами пустую клетку, то есть в клетки с номерами , , и т.д., до тех пор, пока не получим результат «ранен», либо такие клетки не кончатся. Мы сделаем не более, чем выстрелов (целочисленное частное от деления на ). Получив на каком-то выстреле ответ «ранен», начнём стрелять в соседние клетки в одну сторону, а при получении результата «мимо» — в другую сторону. Тем самым мы сделаем не более одного дополнительного промаха, то есть для попадания в клетку корабля понадобятся не более выстрелов, и общее число выстрелов будет равно .
Но если делится на , то последний выстрел из первой последовательности придётся в последнюю клетку поля, и тогда с одной стороны от этой клетки больше не останется клеток. В этом случае достаточно только дополнительных выстрелов, то есть при , делящемся на , ответ равен .
Используя целочисленное деление, оба этих случая можно записать одной формулой.
n = int(input())
k = int(input())
print((n - 1) // k + k)Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long n, k;
cin >> n >> k;
cout << (n - 1) / k + k << "\n";
return 0;
}7. Сломанный индикатор
У радиолюбителя Алексея есть девятисегментный жидкокристаллический индикатор, который может показывать цифры от 0 до 9 в виде цифр «почтового индекса» (см. рисунок):

После неудачного эксперимента индикатор повредился, и часть сегментов могла перегореть. Когда сегмент перегорает, индикатор теряет возможность показывать цифры, использующие этот сегмент.
Алексей уже выяснил, что индикатор всё ещё способен показать какие-то цифр. Однако радиолюбитель не может проверить остальные цифры, равно как и каждый сегмент отдельно. Поэтому он просит вас помочь найти те цифры, которые гарантированно можно показать на этом индикаторе.
Формат входных данных
Первая строка входных данных содержит число () — количество цифр, которые смог показать на индикаторе Алексей.
Следующие строк содержат по одной цифре () — сами цифры, которые Алексей смог показать. Гарантируется, что все различны.
Формат выходных данных
Выведите элементы искомого множества в порядке возрастания, каждую цифру в отдельной строке.
Система оценки
Решения, правильно работающие при , будут оцениваться в 28 баллов.
| стандартный ввод | стандартный вывод |
|---|---|
3 2 4 8 | 0 2 4 5 8 9 |
| стандартный ввод | стандартный вывод |
|---|---|
2 6 1 | 1 6 |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
Для начала формализуем условие задачи. Некий индикатор состоит из 9 сегментов, каждый из которых либо гарантированно работает (зажигается какой-то цифрой из данного набора), либо имеет неизвестное состояние (не зажигается ни одной из данных цифр). Задача заключается в нахождении всех цифр, которые состоят только из гарантированно рабочих индикаторов.
Пронумеруем сегменты индикатора сверху вниз, слева направо, то есть самый верхний сегмент будет иметь номер 1, а самый нижний — 9. Для каждой возможной цифры перечислим сегменты, из которой она состоит. Например, цифра 0 состоит из сегментов 1, 2, 4, 6, 8, 9.
Если какая-то цифра могла быть отображена на экране, то соответствующие ей сегменты заведомо исправны. Если несколько цифр могли быть отображены на экране, то исправны сегменты, которые входят в хотя бы одну данную цифру. То есть нужно сделать объединение множеств сегментов, соответствующих данным цифрам. Это удобно реализовать при помощи структуры данных «множество» в языке Python, но можно использовать и массивы из нулей и единиц (где единица будет соответствовать исправному сегменту индикатора) или битовые операции, но тогда реализация станет сложнее.
Для проверки, что какую-то цифру гарантированно удастся показать на индикаторе, множество сегментов этой цифры должно быть подмножеством заведомо исправных сегментов. Для этого в Python есть операция <= для множеств.
Приведём пример решения на языке Python. Здесь segments — это список множеств, соответствующих цифрам, то есть segments[i] — это список сегментов, входящих в цифру .
После нахождения объединения множеств сегментов переберём все цифры от 0 до 9 и выведем подходящие из них.
segments = [
{1, 2, 4, 6, 8, 9},
{3, 4, 8},
{1, 4, 7, 9},
{1, 3, 5, 7},
{2, 4, 5, 8},
{1, 2, 5, 8, 9},
{3, 5, 6, 8, 9},
{1, 3, 6},
{1, 2, 4, 5, 6, 8, 9},
{1, 2, 4, 5, 7}]
res = set()
n = int(input())
for i in range(n):
d = int(input())
res |= segments[d]
for d in range(0, 10):
if segments[d] <= res:
print(d)Для получения частичного балла при достаточно было вручную исследовать, какие ответы возникают на 7 возможных тестах этой группы, занести их в программу и выводить нужный ответ в зависимости от ввода.
Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
vector<set<int>> segments = {
{1, 2, 4, 6, 8, 9},
{3, 4, 8},
{1, 4, 7, 9},
{1, 3, 5, 7},
{2, 4, 5, 8},
{1, 2, 5, 8, 9},
{3, 5, 6, 8, 9},
{1, 3, 6},
{1, 2, 4, 5, 6, 8, 9},
{1, 2, 4, 5, 7}
};
int n;
cin >> n;
set<int> working;
for (int i = 0; i < n; i++) {
int digit;
cin >> digit;
working.insert(segments[digit].begin(), segments[digit].end());
}
for (int digit = 0; digit < 10; digit++) {
bool ok = true;
for (int segment : segments[digit]) {
if (!working.count(segment)) ok = false;
}
if (ok) cout << digit << "\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 задач