+Оглавление
Разбираем задачу №8 в ЕГЭ по информатике.
Обратите внимание, здесь будет не только пример решения, но и разбор задания по существу.
Для примера я беру демоверсию 2020 года (актуальная на момент написания статьи) с сайта fipi.ru.
Прежде чем приступать к решению этого примера, посмотрим в спецификацию к демоверсии.
Нам говорят, что проверяют знание основных конструкций ЯП, понятие переменной и оператора присваивания. Это не так много, но оно требует тщательного подхода.
В кодификаторе под пунктом 1.7.2 в таблице проверяемых элементов содержания указано примерно то же самое, а в п. 1.1.4 таблицы проверяемых требований говорится, что мы должны уметь читать и отлаживать программы. Это очень важный навык, хоть он и легко приобретается и тренируется.
О чтении алгоритмов
Все готовые алгоритмы без исключения читаются одинаково. Именно поэтому на задания "на чтение алгоритмов" можно натаскать. И всё-таки только сравнительно простое (в смысле теории) задание № 8 имеет высокий процент решаемости, а задание, например, 11, 14, 19 и 21 имеют приличные провалы не только среди "слабой" группы школьников, но даже и среди "сильных" ребят. Значит, дело всё-таки не в натаскивании.
На ЕГЭ не разрешается использовать компьютер для выполнения алгоритмов, поэтому их приходится выполнять вручную, копируя поведение машины. Здесь возникают две фундаментальные проблемы:
1. Некоторые алгоритмы требуют огромного количества сложных вычислений, с которыми машина справится относительно быстро, а человек может засесть очень надолго
2. При отладке программы часто трудно предсказать заранее, какой ответ выдаст машина, если не пройти по алгоритму полностью, поэтому при решении обратных задач программирования (определить входные, при которых получится требуемый результат) часто требуется серьёзный анализ алгоритма и/или выработка стратегии подбора.
Разбор задачи
Задача №8 в ЕГЭ 2020 ого года является простой прямой задачей, поэтому здесь если и возникают трудности, то это не такие, которые я описал выше. Чаще всего, проблема в синтаксисе языка. И синтаксис надо учить, тут уж никуда не денешься. При регулярной практике программирования, подобные вещи будут запоминаться автоматически, но первые шаги, разумеется, стоит делать со справочником по языку. Большинство IDE имеют хороший функционал в этой области (исключение опять составляет Питон: нет IDE - нет справки, а на интернет-ресурсах краткого, удобного и ёмкого справочника нет по причине молодости языка и ограниченности)
Отступление. В ЕГЭ предлагается на выбор 5 языков, на которых написаны равноправные алгоритмы. Я буду работать с синтаксисом Паскаля. Но работать так, чтобы и для "адептов" других языков было всё понятно.
Так как задача может быть совершенно любой (но простой), рекомендую выполнять каждый шаг алгоритма вручную. Эта стратегия приведёт Вас к верному ответу за минимально возможное число шагов. Анализ алгоритма чаще всего требует больше времени, чем прямой подсчёт.
Для этого нам потребуется карандаш, бумага и стирательная резинка, как я описывал в статье про переменные. Программа машиной (и нами) выполняется слева направо, строчка за строчкой (сверху вниз). Первая строка в алгоритме
var s, n: integer;
В общем-то, это очень сложная операция для машины, но мы, не влезая в тонкости, просто нарисуем два квадрата на бумаге, рядом с каждым напишем его название "s" или "n":
На этом можно считать первую строку выполненной: переменные созданы, но не инициализированы. Паскаль (в отличие от некоторых других языков) переменные инициализирует сразу и записывает в них нули. Но в тексте программы инициализация прописана ещё и явно, чего я тоже рекомендую придерживаться.
begin
Это операторная скобка. Она выполняться не будет, но всё, что начинается с begin вплоть до end считается единой конструкцией. В нашем случае - программой. Аналогично все действия в скобках можно считать одним объектом. Обратите внимание, что "бегинов" и "эндов" у нас несколько. Это полная аналогия с математическими скобками: 2+(7*(15+20)/5-7)*13. В этом примере "внутренние" скобки оборачивают (15+10) в один объект, а внешние (7*(15+20)/5-7) включают (15+10) как одну из частей.
s := 0;
Мы должны сейчас в прямоугольник, названный "s" вписать 0. Карандашом!
n := 1;
Мы должны сейчас в прямоугольник, названный "n" вписать 1. Карандашом!
Следом идёт сложная конструкция с операторными скобками (begin - end). Её рассматриваем целиком, как (15+10) в примере выше.
while s < 51 do
begin
s := s + 11;
n := n * 2;
end;
Читать её надо вот как: проверь, верно ли, что число в квадрате "s" < 50, и если это так, то сделай то, что после "do", а потом снова вернись к проверке. После "do" у нас действия в скобках. Их надо делать каждый раз после проверки истинности выражения. 0 < 51 - ИСТИНА. Выполняем:
s := s + 11;
Выполнять надо так: взять, что у нас в этом s записано, прибавить 11. В s у нас лежит 0. 0 + 11 = 11. Вот эти новые 11 мы должны записать в s, предварительно стерев карандашный "нолик" там:
дальше идёт
n := n * 2;
мы должны взять то, что в ячейке n, и умножить на 2: 1 * 2 = 2. И вот эту новую двойку записать в ячейку n.
То, что было в скобках - выполнено. Возвращаемся к проверке условия (как нам и велели)
while s < 51 do
begin
s := s + 11;
n := n * 2;
end;
Опять: проверь, верно ли, что число в квадрате "s" < 50, и если это так, то сделай то, что после "do", а потом снова вернись к проверке. 11 < 51 - ИСТИНА. Выполняем:
s := s + 11;
11 + 11 = 22.
n := n * 2;
2 * 2 = 4.
Снова возвращаемся к проверке 22 < 51... И так далее. Это не так сложно, и Вы можете проделать это самостоятельно.
Важно на первых порах не пропускать ни одного шага.
Последний раз цикл даст такие записи
Обратите внимание, что s:[44] и n:[16] при проверке истинности s<51 (44<51) даст ИСТИНУ, поэтому до 55 и 32х всё-таки догонять придётся. А уже после 55<51 даст ЛОЖЬ, и мы можем перейти к строке, которая идёт после "end;", который относится к while.
writeln (n);
Команду стоит читать так: напиши на экране то, что лежит в ячейке n, а потом переходи на новую строку. Так мы и поступаем: ручкой на чистом листе пишем то, что записано в ячейке n. Это "32"
end.
Завершение работы программы. Точка - конец файла.
Теперь, когда машина в нашем лице выполнила свою работу, можно отвечать на вопрос. Что будет напечатано в результате работы программы? То, что записано на отдельном листе - 32. Это и будет ответом.
Подводные камни
1. Бывает так, что вывод не единичен. Мы должны буквально следовать программе, и тогда узнаем, что на самом деле будет напечатано.
2. Попытка сэкономить и заменить многократное сложение умножением, а умножение - степенью, часто приводит к ошибке на 1-2 раза, и мы получим не 32, а 64 или 16. Чтобы быстро и точно определять, сколько раз пройдёт цикл, нужен приличный опыт отладки таких программ именно в ручном режиме.
Заключение
Такой метод решения кажется громоздким, но в этом задании единственный способ получить гарантированно верный ответ - отладка с выполнением каждого шага. Именно поэтому на задание отводится целых 3 минуты. Опытный программист ответ "увидит" сразу, но даже тогда есть риск ошибиться в разах
Кроме того, на ЕГЭ вообще нельзя пользоваться карандашом и резинкой, и непосредственно стирание-запись невозможны. Но никто не мешает создать таблицу, в которой колонками служат переменные, а строками - шаги программы:
Попробуйте заполнить КАЖДУЮ ячейку в колонках с переменными. Если в строке нет присваивания какой-то переменной, её значение просто переносится из строки выше.
И последнее: Во время тренировок каждую программу обязательно проверяйте в отладчике на компьютере. Если при пробном запуске Вы видите ответ, отличающийся от Вашего, то идите по строчкам: