ЕГЭ · Информатика · Алгоритмы и исполнители
Исполнители и формальное исполнение
Понять, что такое исполнитель, и научиться прогонять алгоритм по шагам.
🎯 ЕГЭ информатика: задания 1, 5, 6, 12, 13, 22, 23, 25, 26, 27. №1 — графы и таблицы смежности; №5 — анализ и построение алгоритмов для исполнителей; №6 — исполнитель Черепаха, геометрия на плоскости; №12 — текстовый исполнитель, обработка строк; №13 — подсчёт числа программ исполнителя; №22 — параллельные и последовательные процессы; №23 — графы из файла: кратчайший путь и число путей.
- ⚠Ищут не то число (наибольшее/наименьшее — читай условие)
- ⚠Забывают обратный ход: удобнее идти от результата к входу
Определение
Исполнитель — объект, выполняющий строго заданный набор команд (СКИ) и не понимающий ничего, кроме них. Задача — предсказать результат или восстановить исходные данные по результату.
Главный навык — аккуратная трассировка: выписывай состояние на каждом шаге в таблицу, не держи промежуточные значения в голове. Для автоматов и преобразований чисел почти всегда быстрее написать программу-переборщик на Python.
Разбор примера
Трассировка алгоритма над двоичной записью
N=5. Алгоритм: перевести N в двоичную запись, приписать справа 0, если число чётное, и 1, если нечётное; результат перевести в десятичную.
Показать решение по шагам
- 1. N=5 — нечётное. Двоичная запись: 101.
- 2. Приписываем справа 1 (число нечётное): 1011.
- 3. Переводим обратно: 1·8+0·4+1·2+1·1 = 11.
- 4. Результат R = 11.
Ответ: R = 11
Откуда взялось слово «алгоритм»
Слово происходит от имени учёного. В IX веке в Багдаде работал Мухаммад ибн Муса аль-Хорезми — математик, астроном и географ. Его книги по арифметике индийскими цифрами перевели в Европе на латынь, и имя автора в латинской передаче — Algorithmi — стало обозначать сам способ вычислений «по правилам».
От названия другой его книги, «Китаб аль-джабр ва-ль-мукабала», произошло слово алгебра.
Смысл этой истории для курса прямой: алгоритм с самого начала понимался как рецепт, которым может воспользоваться кто угодно, не понимая, почему он работает. Достаточно точно выполнять шаги.
Алгоритм — понятное и точное предписание исполнителю совершить конечную последовательность действий, приводящую от исходных данных к результату.
Свойства алгоритма — обязательный перечень, и каждое свойство стоит понимать, а не заучивать:
— дискретность — алгоритм разбит на отдельные завершённые шаги, следующий начинается после окончания предыдущего; — детерминированность (определённость) — на каждом шаге предписано ровно одно действие, и при одних и тех же данных результат один и тот же; «выбери что-нибудь подходящее» алгоритмом не является; — понятность — все команды входят в систему команд исполнителя; команда «нарисуй красиво» Черепахе непонятна; — конечность (результативность) — алгоритм завершается за конечное число шагов и даёт результат либо сообщение о его отсутствии; — массовость — алгоритм применим не к одному набору данных, а к целому классу однотипных задач; — корректность — при допустимых данных выдаётся правильный результат.
Исполнитель и формальное исполнение
Исполнитель — объект, способный выполнять определённый набор команд. Исполнителем может быть человек, робот, станок, процессор.
Исполнитель описывается четырьмя характеристиками:
— система команд — что он умеет; — среда (обстановка) — где он работает: клетчатое поле, числовая переменная, лист бумаги; — допустимые действия и отказы — что произойдёт при недопустимой команде (Робот, идущий в стену, даёт отказ); — режим работы — непосредственное управление (команда за командой) или программное (заранее записанная программа).
Ключевое понятие темы — формальное исполнение: исполнитель выполняет команды не вникая в смысл задачи. Именно это свойство позволило передать вычисления машине.
Отсюда и главный практический совет по заданиям на исполнителей: не угадывайте, что программа «хочет» сделать, — выполняйте её буквально. Больше всего ошибок в заданиях 5, 6, 12 и 13 возникает потому, что ученик «понял идею» и посчитал по своей идее, а не по написанным командам.
Рабочий приём — таблица трассировки. Выпишите столбцы для всех переменных исполнителя и заполняйте по строке на каждый шаг. Это медленнее, чем в уме, и почти всегда быстрее, чем переделывать задачу после неверного ответа.
Способы записи алгоритма: словесное описание, блок-схема, школьный алгоритмический язык, язык программирования. Блок-схема использует устойчивые обозначения: овал — начало и конец, прямоугольник — действие, ромб — ветвление, параллелограмм — ввод и вывод.
Базовые алгоритмические конструкции всего три, и из них собирается любой алгоритм: следование (действия подряд), ветвление (выбор одной из двух ветвей по условию), цикл (повторение). Этот факт — содержание теоремы о структурном программировании: любой алгоритм можно записать, пользуясь только этими тремя конструкциями, без переходов «куда попало».
Переборщик: универсальный ответ на «укажите минимальное N»
Половина заданий про исполнителей формулируется одинаково: описан алгоритм, превращающий число N в число R, и спрашивается минимальное (или наибольшее) N с каким-нибудь свойством результата. Разбирать такие задачи «умом» можно, но на экзамене это долго и ненадёжно.
Есть приём, закрывающий весь класс задач сразу. Он состоит из двух шагов.
Первый шаг — записать алгоритм функцией. Дословно, по пунктам условия, без попыток упростить. Если в условии написано «строится двоичная запись», значит в коде появляется bin(n)[2:]; если «дописывается 00», значит + '00'. Никакой математики, только буквальный перевод — в этом и состоит формальное исполнение.
Второй шаг — перебрать N подряд и остановиться на первом, который подходит:
```python
n = 1
while not uslovie(preobrazovat(n)):
n += 1
print(n)```
Если спрашивают наибольшее N, перебирают до разумной границы и запоминают последнее подошедшее. Границу берут с запасом: в заданиях линии 5 ответы не превышают нескольких тысяч, так что range(1, 100000) отработает мгновенно и заведомо не промахнётся.
Почему этот приём так хорош? Потому что он не требует понимать задачу. Достаточно правильно перевести условие в функцию, а дальше компьютер сам проверит все варианты по порядку. Ошибиться можно только в переводе — и вот его как раз надо перечитать дважды, особенно слова «кратно», «не меньше», «чётное».
И обратная сторона: если алгоритм в условии описан словами про двоичную запись, соблазн работать с числами арифметически ведёт к ошибкам. Работайте со строкой — она и есть «запись», о которой говорит условие.
Разбор примера
Формальное исполнение в таблице: алгоритм с циклом
Исполнитель работает с натуральным числом. Пока число не равно единице, он повторяет: если число чётное — делит его пополам, иначе умножает на 3 и прибавляет 1. Сколько шагов сделает исполнитель, если начать с числа 6?
Показать решение по шагам
- 1. Шаг 1. «Формально исполнить» значит не думать наперёд, а честно выполнять команды и записывать состояние. Заводим таблицу из двух столбцов: текущее число и номер шага. Ничего в уме не держим — вся суть навыка именно в этом.
- 2. Шаг 2. Начало: число 6, сделано 0 шагов. Проверяем условие цикла: 6 не равно 1, значит цикл выполняется.
- 3. Шаг 3. Число 6 чётное → делим пополам: 3, шагов 1. Проверка: 3 не равно 1, продолжаем.
- 4. Шаг 4. Число 3 нечётное → 3 × 3 + 1 = 10, шагов 2. Здесь и проявляется характер такого исполнителя: число не только уменьшается, но иногда растёт, и предсказать длину пути заранее невозможно.
- 5. Шаг 5. 10 чётное → 5, шагов 3. 5 нечётное → 5 × 3 + 1 = 16, шагов 4. 16 чётное → 8, шагов 5.
- 6. Шаг 6. 8 чётное → 4, шагов 6. 4 чётное → 2, шагов 7. 2 чётное → 1, шагов 8. Условие цикла нарушено: число равно 1, исполнитель останавливается. Ответ: 8 шагов, вся цепочка — 6, 3, 10, 5, 16, 8, 4, 2, 1.
- 7.
Шаг 7. Та же трассировка программой:
```python
chislo = 6 shagov = 0 put = [chislo] while chislo != 1: if chislo % 2 == 0: chislo = chislo // 2 else: chislo = 3 * chislo + 1 shagov += 1 put.append(chislo)print(shagov, put) ```
Вывод:
8 [6, 3, 10, 5, 16, 8, 4, 2, 1]— ровно наша таблица. - 8. Шаг 8. Обратите внимание на целочисленное деление
//. Обычное деление/вернуло бы3.0— вещественное число, и уже на следующем сравненииchislo % 2 == 0начнутся сюрпризы, а в выводе появятся точки. В задачах про исполнителей над целыми числами/не используют никогда. - 9. Шаг 9. Второе, что стоит заметить: список
putне нужен для ответа, он нужен для проверки себя. Распечатанная цепочка позволяет мгновенно сверить программу с ручной трассировкой. Если бы в коде стояло3 * chislo - 1, расхождение вылезло бы на втором элементе, а не после получаса поисков. - 10. Шаг 10. И главный вывод про формальное исполнение: исполнитель не понимает смысла. Он не знает, что «цепочка когда-нибудь дойдёт до единицы»; он просто проверяет условие и выполняет команду. Ваша задача при трассировке — стать таким же: выполнять буквально и записывать каждое состояние.
Ответ: 8 шагов
Разбор примера
Линия 5: переводим условие в функцию и перебираем
На вход алгоритма подаётся натуральное число N. Строится двоичная запись N; если N кратно 3, в конец дописывается 00, иначе — 11; полученная запись переводится в десятичную систему — это число R. Указать минимальное N, при котором R не меньше 200.
Показать решение по шагам
- 1.
Шаг 1. Переводим условие в функцию дословно, по пунктам:
```python
def preobrazovat(n): zapis = bin(n)[2:] if n % 3 == 0: zapis = zapis + '00' else: zapis = zapis + '11' return int(zapis, 2)n = 1 while preobrazovat(n) < 200: n += 1print(n, preobrazovat(n)) ```
- 2. Шаг 2. Разберём две незнакомые конструкции. Функция bin(n) возвращает строку вида
'0b1101', и срез[2:]отрезает префикс0b, оставляя чистую двоичную запись. Обратно строку в число переводит int(zapis, 2) — второй аргумент говорит, что запись читается в двоичной системе. Эти две строчки закрывают всю линию 5 и половину линии 14. - 3. Шаг 3. Важнейшая деталь: кратность проверяется у исходного числа N, а не у его записи и не у результата. В условии написано «если N кратно 3» — значит, в коде
n % 3 == 0. Подмена проверяемого объекта — самая частая ошибка в этой линии, и она даёт правдоподобный неверный ответ, который не вызывает подозрений. - 4. Шаг 4. Проследим первые значения. N = 1: запись
1, единица не кратна трём → дописываем11, получается111= 7. Меньше 200, идём дальше. N = 2: запись10→1011= 11. N = 3: запись11, тройка кратна трём →1100= 12. - 5. Шаг 5. N = 4:
100→10011= 19. N = 5:101→10111= 23. N = 6:110, кратно трём →11000= 24. Заметна закономерность: дописывание двух разрядов умножает число примерно на четыре, и добавка 11 даёт на 3 больше, чем добавка 00. - 6. Шаг 6. Дальше перебор идёт быстро: N = 16 даёт 67, N = 25 даёт 103, N = 40 даёт 163. Всё ещё меньше 200, цикл продолжается.
- 7. Шаг 7. N = 49: запись
110001, 49 не кратно трём →11000111= 199. Досадно близко, но условие «не меньше 200» не выполнено, и цикл делает ещё один шаг. - 8. Шаг 8. N = 50: запись
110010→11001011= 203. Условие выполнено, цикл останавливается, программа печатает50 203. Ответ — 50. - 9. Шаг 9. Пара 49 и 50 показывает, зачем нужен перебор: граница проходит между соседними числами, и никакой «оценкой сверху» её не угадать. Заодно видно, почему нельзя перебирать через десять — пропустили бы ровно то значение, которое требуется.
- 10. Шаг 10. Что менять, если спросят иначе? «Наибольшее N, при котором R меньше 200» — перебираем
for n in range(1, 1000)и запоминаем последнее подошедшее (это будет 49). «R — степень двойки» — меняется только условие вwhile. Сам перевод алгоритма в функцию остаётся тем же, и именно поэтому его стоит писать аккуратно: он переиспользуется во всех вариантах формулировки.
Ответ: 50 (при N = 49 получается 199 — на единицу меньше порога)
Разбор примера
Исполнитель Робот: среда, отказ и цикл «пока»
Робот стоит в левом верхнем углу поля 4 × 4 и закрашивает клетки, по которым проходит. Стены — клетки (строка 1, столбец 3) и (строка 3, столбец 1); в них зайти нельзя. Программа: «пока справа свободно — вправо», затем «пока снизу свободно — вниз». Где окажется Робот и сколько клеток будет закрашено?
Показать решение по шагам
- 1. Шаг 1. У исполнителя Робот среда — клетчатое поле со стенами, а система команд состоит из перемещений и проверок обстановки вроде «справа свободно». Попытка шагнуть в стену или за край поля называется отказом: исполнитель не выполняет команду и останавливает программу. Цикл «пока свободно» именно для того и нужен, чтобы до отказа не доводить.
- 2.
Шаг 2. Запишем поле строками, где точка — свободно, а решётка — стена:
- • ```python
- • pole = ['..#.',
- • '....',
- • '#...',
- • '....']
stroka, stolbec = 0, 0 zakrasheno = {(stroka, stolbec)}
def svobodno(r, c): return 0 <= r < 4 and 0 <= c < 4 and pole[r][c] == '.'while svobodno(stroka, stolbec + 1): stolbec += 1 zakrasheno.add((stroka, stolbec))while svobodno(stroka + 1, stolbec): stroka += 1 zakrasheno.add((stroka, stolbec))print(stroka, stolbec, len(zakrasheno)) ```
- 3. Шаг 3. Функция svobodno проверяет сразу две вещи: что клетка существует (координаты внутри поля) и что в ней нет стены. Порядок условий важен: если сначала обратиться к
pole[r][c], а потом проверять границы, программа упадёт при выходе за край. Python вычисляетandслева направо и до первого ложного — это и спасает. - 4. Шаг 4. Множество zakrasheno хранит посещённые клетки. Именно множество, а не счётчик: если Робот пройдёт по клетке дважды, закрашенной она останется одной, а счётчик насчитал бы два. Стартовая клетка добавляется сразу — Робот стоит на ней и закрашивает её.
- 5. Шаг 5. Трассируем первый цикл. Робот в (0, 0). Справа клетка (0, 1) — точка, свободно → шаг вправо, теперь (0, 1), закрашено две клетки.
- 6. Шаг 6. Снова проверка: справа клетка (0, 2) — там стена. Условие ложно, первый цикл заканчивается. Робот остался в (0, 1), и это ключевой момент: цикл «пока» остановился сам, отказа не произошло. Если бы вместо цикла стояли три команды «вправо», третья вызвала бы отказ.
- 7. Шаг 7. Второй цикл. Снизу от (0, 1) клетка (1, 1) — свободна → (1, 1), закрашено три. Снизу (2, 1) — свободна → (2, 1), закрашено четыре. Заметьте: стена (2, 0) находится слева от этой клетки и никак не мешает — Робот идёт вниз, а не влево.
- 8. Шаг 8. Снизу (3, 1) — свободна → (3, 1), закрашено пять. Следующая проверка смотрит на строку 4, которой не существует: функция
svobodnoвозвращает ложь по проверке границ. Второй цикл заканчивается. - 9. Шаг 9. Итог: Робот в клетке (3, 1) — третья строка сверху, второй столбец слева; закрашено 5 клеток: (0,0), (0,1), (1,1), (2,1), (3,1). Программа печатает
3 1 5. - 10. Шаг 10. Чему учит этот разбор. Во-первых, состояние исполнителя — это не только его положение, но и всё, что он изменил в среде (закрашенные клетки). Во-вторых, граница поля ведёт себя как стена, и забыть об этом — классическая ошибка. В-третьих, цикл «пока свободно» — единственный способ написать программу, которая сработает на любом поле, а не только на нарисованном: ровно этого и требуют формулировки вида «программа должна работать при любом расположении стен».
Ответ: Робот в клетке (3, 1), закрашено 5 клеток
Вопрос на проверку
Что означает «формальное исполнение алгоритма»?
Ответить и проверить себя — после бесплатной регистрации.
Задание №5 в формате экзамена
Ответить и проверить себя — после бесплатной регистрации.
Задание №5 в формате экзамена
Ответить и проверить себя — после бесплатной регистрации.