Муниципальный этап, 7–8 классы всероссийской олимпиады по информатике: 6 задач с официальным разбором, к 3 из них наше решение на C++.
К задаче 1Муниципальный этап ВсОШ по информатике 2025/26, 7–8 классы.
Задачи тура
- 1Расстановка знаковматематика, перебор
- 2Замена символовжадный алгоритм, строки
- 3Фабрикаматематика, деление с округлением
- 4Большой квадратматематика, геометрия
- 5Перевозка грузовжадный алгоритм, математика
- 6План эвакуацииреализация, манхэттенское расстояние
Отмечайте решённые: 0 из 6
1. Расстановка знаков
Дано выражение
В этом выражении вместо знаков «» необходимо расставить арифметические операции — по два знака сложения, вычитания, умножения, деления, так, чтобы значение полученного выражения было как можно больше.
Запишите в ответе строку, полученную в результате расстановки знаков в данном выражении: в строке должны быть цифры от 1 до 9 в порядке возрастания, между цифрами должны стоять знаки, необходимо расставить по два знака каждой арифметической операции. Операция умножения обозначается знаком «*», операция деления обозначается знаком «/».
При вычислении выражения сначала выполняются операции умножения и деления слева направо. Например, запись 1*2/3*4 обозначает . Затем выполняются операции сложения и вычитания слева направо. При этом в записи ответа нельзя использовать скобки.
Чем больше будет значение вашего выражения, тем больше баллов вы получите.
Официальный разборСначала попробуйте решить сами
Официальный разбор
Наибольший результат можно получить, если перемножить три наибольших числа и перед ними поставить знак , то есть выражение будет заканчиваться на +7*8*9. Также в выражении будут два слагаемых, которые будут вычитаться. Их нужно сделать как можно меньше, поэтому используем операцию деления, при помощи которой можно получить выражения , , , . Из этих выражений самое маленькое по модулю — это , а следующее по величине, не содержащее цифры 2 и 3, это . Перед цифрой 6 поставим знак .
Ответ: 1-2/3-4/5+6+7*8*9.
2. Замена символов
Дана строка, которая может содержать только буквы «A», «B», «C», «D», «E», «F». Вам нужно заменить буквы на числа «1», «2», «3», «10», «20», «30». Одинаковые буквы должны быть заменены на одинаковые числа, разные буквы — на разные числа. Например, если «A» заменить на «1», «B» заменить на «2», а «C» заменить на «10», то из строки «ABACABA» получится число «12110121».
Вам нужно придумать такой способ замены букв на числа, чтобы полученное из строки число было как можно меньше. При этом для разных заданий можно использовать разные замены.
Ответьте на вопросы.
1. Какое минимальное число может получиться из строки «ABAABB»?
2. Какое минимальное число может получиться из строки «BABACCCA»?
3. Какое минимальное число может получиться из строки «DBACCADC»?
4. Какое минимальное число может получиться из строки «EEEEEDDDDCCCBBA»?
5. Какое минимальное число может получиться из строки «ABBCCDDEEFFF»?
Официальный разборСначала попробуйте решить сами
Официальный разбор
В строке «ABAABB» нужно букву A заменить на 1, а букву B заменить на 2, получится число 121122.
В строке «BABACCCA», чтобы получить минимальное число, нужно заменить B на 1, A на 2 и C на 3, получится 12123332.
В строке «DBACCADC» используются четыре цифры, поэтому придётся использовать двузначные числа. Чтобы результат получился как можно меньше, прежде всего нужно минимизировать количество цифр в результате. Поэтому для замен будем использовать числа 1, 2, 3 и 10. В данной строке буква B встречается один раз, остальные буквы встречаются два и более раза, поэтому число будет самым коротким, если B заменить на 10. Оставшиеся буквы заменим на 1, 2, 3 в порядке их появления в строке, то есть D на 1, A на 2, C на 3. Получится 110233213.
В строке «EEEEEDDDDCCCBBA» буквы A, B, C, D, E встречаются 1, 2, 3, 4, 5 раз соответственно. Поэтому наиболее частые буквы C, D, E заменим на однозначные числа 1, 2, 3, а буквы A и B — на двузначные числа 10 и 20. Какие именно буквы на какие цифры менять определяется тем, какая буква встречается в строке раньше. Ответ: 111112222333101020.
В строке «ABBCCDDEEFFF» буква A встречается один раз, она будет заменена на двузначное число. Буква F встречается три раза, она будет заменена на однозначное число. Буквы B, C, D, E встречаются по два раза, и для них можно использовать как однозначные, так и двузначные числа. Пройдём по строке слева направо. A заменим на минимальное двузначное число 10. За ней идёт буква B, её можно заменить на двузначное 20 или однозначное 1. Чтобы результат был меньше, нужно использовать 1. Следующую букву C можно заменить на 20 или 2, во всех случаях длина результата будет одинаковой. Но лучше использовать число 20, т.к. в нём после цифры 2 идёт минимальная цифра 0. Для буквы D будем использовать число 3, а для следующей буквы E — число 30, т.к. число 3 нужно оставить для буквы F. Ответ: 10112020223030333.
3. Фабрика
Бумажная фабрика ежедневно производит пачек бумаги. Произведённые пачки поступают на склад, где упаковываются в коробки по штук. Коробки отправляются заказчикам (заказать на фабрике можно только целое число коробок). Если число произведённых за день пачек не делится на , то бумага остаётся на складе, пока не накопится пачек для упаковки в коробку.
Для проведения экзаменов в Москве требуется очень много бумаги — пачек. Определите количество дней, необходимых для производства и отправки такого заказа.
Рассмотрим пример. Пусть , , . Для того чтобы получить от фабрики 27 пачек бумаги, необходимо заказать 6 коробок по пачек. В первый день будет произведено 14 пачек, из них сделают 2 коробки, и 4 пачки останутся на складе. Во второй день произведут ещё 14 пачек, вместе с 4 имеющимися на складе пачками получится 18 пачек. Из них сделают 3 коробки и ещё 3 пачки останется на складе. Итого за два дня произвели 5 коробок, а для отправки 6 коробок понадобятся 3 дня. Для такого примера ответ равен 3.
Для выполнения этого задания вам даны 20 наборов значений , , . Вы должны найти ответ для этих наборов данных. Данные содержатся в файле, который вы можете скачать в формате электронной таблицы Libre Office Calc или Microsoft Excel. В одной строке таблицы записаны значения , , для одного набора в первых трёх столбцах, именно в таком порядке. Также вы можете скачать файл csv, в каждой из 20 строк которого записаны числа , , через запятую.
Вам необходимо получить ответ для каждого из 20 наборов. Для проведения вычислений вы можете использовать любые средства компьютера, например, электронные таблицы или языки программирования. Ответ нужно записать в виде 20 чисел, ответ на каждый набор данных записывается в отдельной строке. Всего в ответе должны быть 20 строк, содержащих ровно по одному целому числу. Если вы не можете дать ответ для какого-либо набора, нужно написать любое целое число. Каждый правильный ответ будет оцениваться в 5 баллов. Ничего, кроме ответа на данные тестовые наборы, сдавать не надо.
Официальный разборСначала попробуйте решить сами
Официальный разбор
Для решения задачи нужна операция деления с округлением вверх, то есть если результатом деления является дробное число, его нужно округлить до большего целого числа. Например, если в одной коробке 5 пачек бумаги, то для того, чтобы заказать 27 пачек бумаги, необходимо 6 коробок, т.к. . Будем обозначать результат деления на с округлением вверх, как .
Для того, чтобы заказать пачек бумаги в коробках по штук необходимо коробок. Общее число пачек бумаги в этих коробках равно коробок. Количество дней, за которое фабрика поизведёт такое количество бумаги, производя ежедневно по пачек, равно .
Далее нам нужно вычислить эти значения для 20 заданных наборов , , . Это можно сделать разными способами: используя электронные таблицы, написав программу или даже выполняя вычисления на калькуляторе (например, используя приложение «калькулятор» на компьютере).
В электронных таблицах можно вычислить частное при помощи операции «/», а затем результат округлить вверх при помощи функции ROUNDUP (в русском интерфейсе ОКРУГЛВВЕРХ). Запишем в ячейку D2 таблицы формулу =ROUNDUP(ROUNDUP(C2/B2)*B2/A2), скопируем её и вставим в ячейки блока D2:D21. Затем выделим этот блок, скопируем и вставим в поле для ввода ответа.
В программе на языке Python вычислить можно при помощи выражения (a + b - 1) // b. Поэтому для данных значений , , ответ можно найти при помощи программы
p = (t + k - 1) // k * k
ans = (t1 + n - 1) // n
Далее можно написать программу, которая вычисляет ответ для введённых чисел , , и ввести 20 тестовых примеров по одному, или написать одну программу, которая будет выдавать ответ сразу для всех 20 тестовых примеров.
Ответ на это задание.
2
7
106
5
175
90
38
672
301
74
1044
133
5664
41464
3441
129283
1218816
4811850
60638
385362924. Большой квадрат
Даны два прямоугольника размера и . Можно соединить их вместе, приложив сторону одного прямоугольника к стороне другого и склеив место соединения. Прямоугольники можно поворачивать перед склеиванием. После этого из полученной фигуры нужно вырезать квадрат со сторонами, параллельными сторонам прямоугольника. Определите максимальное возможное значение стороны квадрата.
На рисунке изображены два прямоугольника со сторонами и , из которых можно вырезать квадрат со стороной 5 (заштрихован).

Формат входных данных
Программа получает на вход натуральные числа , , , , каждое в отдельной строке — стороны первого и второго прямоугольников. Все числа не превосходят .
Формат выходных данных
Программа должна вывести одно целое число — максимальную возможную сторону квадрата.
| стандартный ввод | стандартный вывод |
|---|---|
6 2 3 8 | 5 |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
Рассмотрим разные способы разместить квадрат внутри двух прямоугольников. Если квадрат полностью размещён внутри первого прямоугольника, то максимально возможная длина стороны равна наименьшей стороне прямоугольника . Если он полностью размещён внутри второго прямоугольника, то . Наконец, рассмотрим вариант, когда для вырезания квадрата понадобятся оба прямоугольника, как на картинке в условии. Пусть прямоугольники сложены так, что стороны и являются продолжением друг друга, а стороны и касаются. Тогда длина стороны квадрата не может быть больше значений , и , и ответом будет . Очевидно, что в этом случае нужно выбрать стороны так, чтобы была наименьшей стороной первого прямоугольника, то есть . Аналогично, должна быть наименьшей стороной второго прямоугольника, то есть .
Итак, если упорядочить стороны прямоугольников, то есть сделать так, что и , то ответ равен
Пример такого решения.
a = int(input())
b = int(input())
c = int(input())
d = int(input())
if a > b:
a, b = b, a
if c > d:
c, d = d, c
print(max(a, c, min(a + c, b, d)))Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long a, b, c, d;
cin >> a >> b >> c >> d;
if (a > b) swap(a, b);
if (c > d) swap(c, d);
cout << max({a, c, min({a + c, b, d})}) << "\n";
return 0;
}5. Перевозка грузов
Необходимо погрузить грузов на тележки. Грузы делятся на три вида в зависимости от их массы, которая записывается целым числом килограммов. Тяжёлые грузы весят 100 и более килограммов. Средние весят от 50 до 99 килограммов. Лёгкие весят не более 49 килограммов.
На одной тележке можно перевезти
- один любой груз;
- два лёгких груза;
- один лёгкий и один средний груз.
Определите минимальное число тележек, необходимое для размещения всех грузов.
Формат входных данных
Первая строка входных данных содержит натуральное число , — количество грузов. Следующие строк содержат по одному целому числу от 1 до 150 — массы грузов.
Формат выходных данных
Программа должна вывести одно целое число — минимальное число тележек.
Замечание
В примере из условия один тяжёлый груз, два средних и один лёгкий. Понадобятся три тележки. На одну тележку положим тяжёлый груз, на вторую — средний груз, на третью — средний и лёгкий грузы.
| стандартный ввод | стандартный вывод |
|---|---|
4 50 40 80 120 | 3 |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
Считаем число n, затем считаем циклом n масс, увеличивая на 1 одну из трёх переменных cnt_heavy, cnt_medium, cnt_light — количество тяжёлых, средних и лёгких грузов. После считывания данных найдём ответ. Тяжёлые грузы занимают по одной тележке, поэтому в ответе будет слагаемое cnt_heavy. Общее число лёгких и средних грузов равно cnt_medium + cnt_light. На каждую тележку можно поместить не более двух таких грузов, поэтому число тележек не может быть меньше половины от этой суммы, округлённой вверх. Также на каждую тележку можно положить не более одного среднего груза, поэтому число тележек для перевозки средних и лёгких грузов не может быть меньше, чем cnt_medium. Поэтому число тележек для перевозки лёгких и средних грузов равно max(cnt_medium, (cnt_medium + cnt_light + 1) // 2).
Пример решения на языке Python.
n = int(input())
cnt_heavy = 0
cnt_medium = 0
cnt_light = 0
for i in range(n):
a = int(input())
if a >= 100:
cnt_heavy += 1
elif a >= 50:
cnt_medium += 1
else:
cnt_light += 1
print(cnt_heavy + max(cnt_medium, (cnt_medium + cnt_light + 1) // 2))Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
int heavy = 0, medium = 0, light = 0;
for (int i = 0; i < n; i++) {
int mass;
cin >> mass;
if (mass >= 100) heavy++;
else if (mass >= 50) medium++;
else light++;
}
cout << heavy + max(medium, (medium + light + 1) / 2) << "\n";
return 0;
}6. План эвакуации
Этаж здания представляет собой прямоугольник из квадратных комнат. Из каждой комнаты есть проходы в соседние комнаты. В двух комнатах находятся лестницы. Необходимо разработать план эвакуации — указать для каждой комнаты направление движения в одну из соседних комнат так, чтобы, передвигаясь по комнатам только в указанных направлениях, можно было бы достичь одной из двух лестниц, пройдя минимальное расстояние.
На рисунке изображён возможный план эвакуации для примера из условия. Комнаты с лестницами обозначены звёздочками.

Формат входных данных
Первая строка входных данных содержит число — количество строк в плане эвакуации, . Вторая строка входных данных содержит число — количество столбцов в плане эвакуации, . Следующие две строки содержат числа и — номера строки и столбца комнаты, в которой находится первая лестница, , . Следующие две строки содержат числа и — номера строки и столбца комнаты, в которой находится вторая лестница, , . Гарантируется, что или . Строки нумеруются сверху вниз числами от 1 до , столбцы нумеруются слева направо числами от 1 до .
Формат выходных данных
Программа должна вывести строк, каждая строка должна содержать символов. Каждый символ соответствует одной комнате. В двух комнатах с лестницами должен находиться символ «S» (прописная английская буква). В остальных комнатах находятся символы, указывающие направление движения:
- «
<» (символ «меньше») — налево. - «
>» (символ «больше») — направо. - «
^» (символ находится на клавише «6») — вверх. - «
v» (строчная английская буква) — вниз.
Никакие другие символы, например, пробелы, выводить не нужно. Вы можете вывести любой подходящий план эвакуации.
Замечание
Решения, правильно работающие, когда , будут оцениваться в 20 баллов.
Решения, правильно работающие, когда , будут оцениваться в 20 баллов.
Решения, правильно работающие, когда лестницы находятся в двух противоположных углах здания, будут оцениваться в 20 баллов.
| стандартный ввод | стандартный вывод |
|---|---|
3 5 1 2 2 4 | >S<v< >^>S< >^>^< |
Официальный разборСначала попробуйте решить сами
Наше решение на C++Полный код на C++17
Официальный разбор
Если комната имеет координаты , то расстояние до лестницы с координатами равно (так называемое «манхэттенское расстояние»). Посчитаем минимум расстояний от комнаты до двух лестниц. Из комнаты нужно перейти в ту из четырёх соседних комнат, для которой минимум расстояний до лестниц будет меньше, чем в этой комнате. Именно в эту комнату и направим стрелку из текущей комнаты. Задача имеет только реализационную трудность.
В примере решения ниже используются вспомогательные функции. dist возвращает расстояние между двумя комнатами, а dist_to_exit — расстояние от комнаты до ближайшей лестницы. Вложенными циклами проходим по всем комнатам. Для перебора направлений переходов в соседние комнаты удобно использовать цикл, в котором переменная c — это символ, соответствующий направлению перемещения, а переменные dx и dy — это значение изменения координат при переходе в данном направлении.
n = int(input())
m = int(input())
y1 = int(input())
x1 = int(input())
y2 = int(input())
x2 = int(input())
def dist(a1, b1, a2, b2):
return abs(a1 - a2) + abs(b1 - b2)
def dist_to_exit(y, x):
return min(dist(y, x, y1, x1), dist(y, x, y2, x2))
for y in range(1, n + 1):
for x in range(1, m + 1):
curr_dist = dist_to_exit(y, x)
move = 'S'
for c, dy, dx in [('^', -1, 0), ('v', 1, 0), ('<', 0, -1), ('>', 0, 1)]:
if dist_to_exit(y + dy, x + dx) < curr_dist:
move = c
print(move, end='')
print()Многие участники написали решение по-другому. Для каждой комнаты сначала определим, к какому из двух выходов нужно двигаться, сравнив расстояния от комнаты до выходов. Пусть координаты рассматриваемой комнаты , а ближайший выход находится в комнате . Если , нужно вывести указатель «вниз», если — указатель «вверх». Если — указатель «вправо», а если —- указатель «влево».
Наконец, встречались и решения с нахождением кратчайшего маршрута при помощи алгоритма обхода графа в ширину, но в этой задаче это избыточно сложное решение.
Наше решение на C++
#include <bits/stdc++.h>
using namespace std;
int n, m, r1, c1, r2, c2;
int distToExit(int r, int c) {
return min(abs(r - r1) + abs(c - c1), abs(r - r2) + abs(c - c2));
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> r1 >> c1 >> r2 >> c2;
const char symbols[4] = {'^', 'v', '<', '>'};
const int dr[4] = {-1, 1, 0, 0};
const int dc[4] = {0, 0, -1, 1};
for (int r = 1; r <= n; r++) {
string line;
for (int c = 1; c <= m; c++) {
int current = distToExit(r, c);
char move = 'S';
for (int k = 0; k < 4; k++) {
int nr = r + dr[k], nc = c + dc[k];
if (nr < 1 || nr > n || nc < 1 || nc > m) continue;
if (distToExit(nr, nc) < current) {
move = symbols[k];
break;
}
}
line += move;
}
cout << line << "\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 задач