Pascal ABC

 

ГЛАВНАЯ
ССЫЛКИ
ОЛИМПИАДНЫЕ ЗАДАНИЯ
Очень простые

Проблема с A и B

Трамвайные билеты

Шифр Цезаря

Четные и нечетные члены последовательности

"Мы вас упакуем!"

Простые

Равновеликие прямоугольники

Скобки

 

Уравнение

 

Вирусы

 

КВН

 

Коррекция кода

 

Степень

 

Демократия в опасности

 

Пуговицы

 

A to B

 

Палиндромы

 

Почти Крэг Туми

 

Виза

 

Ездец

 
Средней сложности  

MIME64

 

Куль хацкеры

 

Редкое имя

 

Города

 

Исправления

 

Банки

 

2^n

 

Ниточка

 

Массивище

 

Знакомые

 

Считаем кораблики

Лошадью ходи!

Левые повороты

Прицельное метание помидор

Анаграммы

Треугольник

Принцип компании

Уникальная строка

Конфуз

K-ичные числа

Михаил Густокашин против бюрократии

Агенты

Игра в слова

Сложные

Диски

Домино

Монеты

Программистика

Хитрющая строка

Робот-сапер

Квадраты

Упаковка простых

Оппозиция

 

Замок

 

Многоугольники

 

Электронные часы

 

Дождик

 

Черепаха

 

Метро

 

Террористы

 

Школы

 
Очень сложные/особо интересные  

Система Защиты

 

Бизнес-классики

 

Телеметрия

 

Лесной пожар

 

Олимпиада

 

Автобусный диспетчер

 

 Кубики

 

Электронная почта

 

Автобус

 

 

 

 

ОЛИМПИАДНЫЕ ЗАДАНИЯ

Олимпиадные задачи с рекомендациями к решениям

Задача 48: Робот-сапер

Программа робота-сапера состоит из последовательности команд вида (a, b), где a - символ, принимающий значения W, N, O или S, что означает, соответственно, запад, север, восток или юг, а b - натуральное число, b < 20. Исполняя команду (a, b), робот делает шаг длины b в направлении a. Робот программируют и запускают из некоторой исходной точки на минное поле. Выполняя друг за другом команды программы, робот обезвреживает встречающиеся ему мины и после каждого шага сообщает, что соответствующая команда выполнена. Проторенная им тропа считается безопасной. Не поступление от робота очередного сообщения означает, что он все же подорвался. В этом случае на его замену из той же исходной точки запускают аналогичный робот. При программировании второго робота возникает следующая задача: найти такую последовательность команд, выполняя которую робот дойдет от исходной точки до места, из которого было получено последнее сообщение предыдущего робота; будет двигаться при этом только по участкам безопасной тропы; пройдет при этом путь минимальной длины.
Требуется написать программу, которая решает эту задачу.
Ввод данных организовать из файла input.txt или с клавиатуры, а вывод - в файл output.txt или на экран.

Формат входных данных:

1-я строка: K (K < 20) - количество команд, которые успел выполнить первый робот;
2-я строка: "a" "пробел" "b" - значения параметров 1-ой из этих команд;
3-я строка: "a" "пробел" "b" - значения параметров 2-ой из этих команд;
K+1-я строка: "a" "пробел" "b" - значения параметров K-ой из этих команд.

Формат выходных данных:

1-я строка: M - количество команд искомой последовательности;
2-я строка: "a" "пробел" "b" - значения параметров 1-ой из этих команд;
3-я строка: "a" "пробел" "b" - значения параметров 2-ой из этих команд;
M+1-я строка: "a" "пробел" "b" - значения параметров M-ой из этих команд.

Ограничение времени: 20 секунд.

Пример входных данных:

4
W 4
N 2
O 2
S 3

Пример выходных данных (соответствуют приведенным входным):

2
W 2
S 1

Решение:
Что-то эта задачка у меня давно лежит решенная, а руки никак не дойдут разобрать. Ну что ж теперь настал и ее черед.
Во первых, надо завести массив 200*200 и закольцевать его (т.е. если вышли за левый край то переходим на правый) из элементов word или integer. Если у вас нет ограничений с памятью (например вы пишите на Free Pascal или на чем-нибудь подобном) заведите массив 400*400 и не закольцовывайте его. Такие размеры массивов объясняются тем, что в одном направлении робот может пройти не более 10 раз максимум по 20 клеток (если я правильно понял условие задачи). Заполним первоначально весь массив элементами 65536 или -1. Из точки (1; 1) начнем ползти соответственно инструкциям (N - вверх, S - вниз и т.д.) и заполнять все клетки, по которым проходит робот элементами 0.
Полностью выполнив все инструкции мы получим лабиринт, в котором клетки, по которым можно идти - нули, а заблокированные - не нули (логично). Для поиска кратчайшего пути в лабиринте необходимо употребить алгоритм заливки (он уже употреблялся  в задаче Лошадью ходи!). Здесь мы пойдем от конечной точки во все стороны тем же самым нерекурсивным флудом. Область возможных значений здесь будет не все поле, а только небольшая (на первых шагах) часть, что позволит разогнать программу. Надо запомнить минимальную, максимальную, самую правую и левую координаты и, в случае, если мы вышли за эти границы, то их необходимо соответственным образом(с закольцованным массивом можно так не делать - замучаетесь, да и размер у него поменьше). Итак, в конечной клетке 0, затем проверяем четыре соседние клетки и в те, которые доступны ставим 1. Затем проверяем всю область на наличие 1 и т.д.
Как только мы нафлудим до начальной точки, то необходимо начать распутывать всю нашу конструкцию. Находим точку, на которую можно перейти с начальной точки (которая хранит значение X - общее количество шагов), и определяем в каком направлении надо двигаться. Двигаемся сколько можем (так чтобы координата следующей клетки в этом направлении была меньше на 1), считаем шаги. Как только придем к ситуации, что в этом направлении двигаться не можем, ищем новое доступное направление, выводим предыдущее направление и количество пройденных шагов. Вот если бы еще требывалось найти наименьшее количество команд с наименьшей длиной пути, то тогда пришлось писать перебор...

Далее ð

 

 
 

СЕРВИС

Copyright © 2008 СОШ №2 им. Н.П. Массонова г.Свислочь © Синица А.А.