Задание №15 — Алгоритмы и программирование
Исполнитель Робот умеет перемещаться по лабиринту, начерченному на плоскости, разбитой на клетки. Между соседними (по сторонам) клетками может стоять стена, через которую Робот пройти не может.
У Робота есть девять команд. Четыре команды – это команды-приказы:
вверх вниз влево вправо
При выполнении любой из этих команд Робот перемещается на одну клетку соответственно: вверх ↑, вниз ↓, влево ←, вправо →. Если Робот получит команду передвижения сквозь стену, то он разрушится.
Также у Робота есть команда закрасить,при которойзакрашивается клетка, в которой Робот находится в настоящий момент.
Ещё четыре команды – это команды проверки условий. Эти команды проверяют, свободен ли путь для Робота в каждом из четырёх возможных направлений:
сверху свободно снизу свободно слева свободно справа свободно
Эти команды можно использовать вместе с условием «eсли», имеющим следующий вид:
если условие то
последовательность команд
все
Здесь условие – одна из команд проверки условия.
Последовательность команд – это одна или несколько любых команд-приказов.
Например, для передвижения на одну клетку вправо, если справа нет стенки и закрашивания клетки, можно использовать такой алгоритм:
если справа свободно то
вправо
закрасить
все
В одном условии можно использовать несколько команд проверки условий, применяя логические связки и, или, не, например:
если (справа свободно) и (не снизу свободно) то
вправо
все
Для повторения последовательности команд можно использовать цикл «пока», имеющий следующий вид:
нц пока условие
последовательность команд
кц
Например, для движения вправо, пока это возможно, можно использовать следующий алгоритм:
нц пока справа свободно
вправо
кц
Выполните задание.
На бесконечном поле имеются две горизонтальные стены одинаковой длины, расположенные точно одна над другой. Длина стен неизвестна. Расстояние между стенами неизвестно. Робот находится над нижней стеной в клетке, расположенной у её левого края.
На рисункеуказан один из возможных способов расположения стен и Робота (Робот обозначен буквой «Р»):

Напишите для Робота алгоритм, закрашивающий все клетки крайнего левого ряда, расположенные между стенами, и клетку, расположенную у правого края под верхней горизонтальной стеной. Робот должен закрасить только клетки, удовлетворяющие данному условию. Например, для приведённого выше рисунка Робот должен закрасить следующие клетки (см. рисунок):

Конечное расположение Робота может быть произвольным. Алгоритм должен решать задачу для произвольного размера и любого допустимого расположения стен. При исполнении алгоритма Робот не должен разрушиться, выполнение алгоритма должно завершиться.
Алгоритм может быть выполнен в среде формального исполнителя или записан в текстовом редакторе.
Сохраните алгоритм в формате программы Кумир или в текстовом файле. Название файла и каталог для сохранения Вам сообщат организаторы экзамена.
Проверка решения с помощью ИИ доступна авторизованным пользователям
Решение.
Для решения задачи разделим алгоритм на несколько логических этапов. Робот начинает движение в левом краю над нижней стеной.
Шаг 1: Закрашивание левого вертикального ряда.
Робот находится в первой клетке, которую нужно закрасить. Нам необходимо двигаться вверх до тех пор, пока мы не упрёмся в верхнюю стену. В каждой клетке на этом пути (включая начальную и конечную под верхней стеной) нужно выполнить команду закрасить.
Используем цикл: пока сверху свободно, закрашиваем текущую клетку и перемещаемся вверх. Когда цикл завершится, Робот окажется в самой верхней клетке левого ряда (прямо под верхней стеной). Эту клетку тоже нужно закрасить.
Шаг 2: Перемещение к правому краю верхней стены.
Теперь Робот находится под левым краем верхней стены. Нам нужно переместиться к её правому краю. Мы знаем, что стена сплошная, поэтому будем двигаться вправо, пока сверху не свободно (то есть пока над Роботом есть стена).
Важно: чтобы закрасить только последнюю клетку, в этом цикле команду закрасить мы не используем.
Шаг 3: Закрашивание последней клетки.
После того как цикл из шага 2 завершится, Робот выйдет за пределы стены (сверху станет свободно). Значит, нужная нам клетка (крайняя правая под стеной) была на один шаг раньше. Однако, можно изменить условие: двигаться вправо, пока справа стена НЕ кончилась, но так как нам нужно закрасить именно клетку у правого края под стеной, мы можем просто дойти до конца стены и закрасить последнюю клетку, где сверху ещё была стена.
Итоговый алгоритм:
использовать Робот
алг
нач
нц пока сверху свободно
закрасить
вверх
кц
закрасить | закрашиваем верхнюю клетку левого ряда
нц пока не сверху свободно
если справа свободно то
вправо
иначе
выход
все
если сверху свободно то | если вышли за край стены
влево | возвращаемся на одну клетку назад под стену
закрасить
вправо | уходим с закрашенной клетки, чтобы цикл завершился
все
кц
кон
Оптимизированный вариант (проще):
1. нц пока сверху свободно: закрасить, вверх. кц
2. закрасить (левый верхний угол).
3. нц пока справа свободно: вправо. Внутри проверяем: если не сверху свободно то — ничего не делаем, просто идем до конца. Чтобы найти именно крайнюю клетку под стеной, лучше использовать такой цикл:
нц пока справа свободно и не сверху свободно: вправо. кц. Если мы остановились, потому что стена кончилась, надо вернуться на шаг назад и закрасить.
Правильный лаконичный алгоритм:
нц пока сверху свободно
закрасить
вверх
кц
закрасить
нц пока справа свободно
вправо
если не сверху свободно то
если справа свободно и сверху свободно то
влево закрасить вправо
все
если не справа свободно то закрасить все
все
кц
Ответ:
использовать Робот
алг
нач
нц пока сверху свободно
закрасить; вверх
кц
закрасить
нц пока справа свободно
вправо
если сверху свободно то
влево; закрасить; вправо; выход
все
если не справа свободно то
закрасить
все
кц
кон
Источник: ФИПИ