Алгоритмы_прохождения_лабиринтов

advertisement
Проектно-исследовательская работа на тему
«Алгоритмы прохождения лабиринтов».
Творческое название проекта: «Выход есть!»
Работу выполнила:
Волкова Е.И.
2011г.
1
Содержание
1.
Введение…………………………………………………………………………………
3
2.
Основные понятия………………………………………………………………….
4
3.
Способы представления лабиринта……………………………………..
5
4.
Метод перебора с возвратом………………………………………………..
5
5.
Характеристика метода перебора с возвратом…………………….
8
6.
Другие методы прохождения лабиринта……………………………..
8
7.
Волновой алгоритм………………………………………………………………..
8
8.
Копилка задач………………………………………………………………………..
12
9.
Заключение……………………………………………………………………………
18
2
Введение
Часто на олимпиадах по информатике можно встретить задачи
связанные с прохождением лабиринта. Решение такого рода задач не входит
в обязательную часть программы по информатике и ИТ.
Цель проекта: научиться решать задачи, связанные с прохождением
лабиринта, средствами языка Pascal.
Согласуясь с целью проекта, были выдвинуты следующие задачи:
1. Выяснить, какими способами может быть задан лабиринт в
программе?
2. Изучить метод перебора с возвратом, как «лобовой» способ решения
задачи на прохождения лабиринта.
3. Ответить на вопрос: всегда ли классическая программа перебора с
возвратом, решает поставленную задачу на прохождение лабиринта,
без внесения, каких-либо коррективов в текст программы?
4. Существуют ли другие алгоритмы прохождения лабиринтов? И, если
они существуют то, какие, и всегда ли они приемлемы.
5. Если существуют другие методы прохождения лабиринта, то
привести пример задачи и представить ее решение, где идея
решения основана на использовании метода, отличного от
переборного. Обосновать его эффективность.
6. Отыскать несколько задач, сводящихся к прохождению лабиринта,
для создания копилки задач.
3
Основные понятия
Массив — упорядоченный набор данных, для хранения данных одного типа,
идентифицируемых с помощью одного или нескольких индексов.
В простейшем случае массив имеет постоянную длину и хранит единицы
данных одного и того же типа.
Количество используемых индексов массива может быть различным.
Массивы с одним индексом называют одномерными, с двумя —
двумерными и т. д. Одномерный массив нестрого соответствует вектору в
математике, двумерный — матрице. Чаще всего применяются массивы с
одним или двумя индексами, реже — с тремя, ещё большее количество
индексов встречается крайне редко.
Граф — это совокупность непустого множества вершин, соединенных между
собой ребрами.
Объекты представляются как вершины, а связи — как рёбра. Для разных
областей применения виды графов могут различаться направленностью,
ограничениями на количество связей и дополнительными данными о
вершинах или рёбрах.
Многие структуры, представляющие
практический интерес в математике и
информатике, могут быть представлены графами.
Неориентированный граф – это граф, где путь между вершинами
пролегает в обоих направлениях.
Ориентированный граф – это граф, где ребра, соединяющие
вершины показывают направление пути от одной вершины к другой.
Матрица смежности - таблица, где как столбцы, так и
строки соответствуют вершинам графа. В каждой
ячейке этой матрицы записывается число,
определяющее наличие связи от вершины-строки к
вершине-столбцу (либо наоборот).
Например, матрица смежности для
неориентированного графа, представленного на
первом рисунке:
4
1
2
3
4
5
6
1
0
1
0
0
0
0
2
1
0
1
1
1
0
3
0
1
0
1
0
0
4
0
1
1
0
1
0
5
0
1
0
1
0
1
6
0
0
0
0
1
0
Способы представления лабиринта
Лабиринт может быть представлен прямоугольной матрицей числового
или символьного типа. На профиль лабиринта накладывается сетка так, что в
каждой ее ячейке находится либо стена, либо проход. Матрица отражает
заполнение сетки: элементы, соответствующие проходу равны, например, 0
– если речь идет о числовой матрице или пробелу – если речь идет о
символьной матрице, а элементы, соответствующие стене, могут быть,
например, буквой S (в символьной матрице) или числом 1 (в числовой). Путь
движения по лабиринту в символьной матрице будет отмечаться какой-либо
литерой (например, «+»), а в числовой – каким-то числом (например, 2).
Иногда лабиринт может содержать другие преграды или, напротив,
бонусы. В этом случае, матрица усложняется, дополнительными значениями.
Но не все задачи о лабиринте имеют такое явное задание его профиля.
Иногда лабиринт может представлять собой ориентированный или
неориентированный граф. В этом случае, его удобно представить матрицей
смежности соответствующего графа (см. Основные понятия).
Метод перебора с возвратом
Рассмотрим классическое решение задачи на прохождение лабиринта.
Задача: «Любитель компьютерных игр заблудился в настоящем (не
виртуальном!) лабиринте. К счастью он взял с собой мобильный телефон,
снял на видео свои блуждания по лабиринту и послал их своему другу
программисту. Программист сумел определить по видеозаписям форму
лабиринта и текущие координаты своего заблудившегося друга. Нужно
помочь найти кратчайший выход из лабиринта. Известно, что лабиринт
размером MxN. Там, где стена стоит символ S, а там где пусто – символ
пробела».
Решение: требуется написать программу, которая по заданному
описанию лабиринта напечатает все возможные пути выхода из него.
Формат входных данных:
Первая строка содержит размерность лабиринта, а именно М – число
строк в описании лабиринта, и N – число столбцов (M, N <15). Далее вводится
5
символьная матрица MxN, содержащая описание лабиринта, где символ «S»
символизирует стену, а пробел символизирует проход. Затем вводятся
координаты путника (номер строки и столбца (x,y), где он находится в
текущий момент).
Формат выходных данных:
Для каждого найденного пути выхода из лабиринта должно быть
напечатано описание лабиринта, т.е. матрица лабиринта, где клеточки, по
которым пролегает «путь» должны быть помечены знаками «+». Если путь
выхода не единственный, между двумя такими «выводами пути»
необходимо оставлять одну пустую строку.
Алгоритм перебора с возвратом еще называют методом проб. Суть его в
следующем:
1) из каждой очередной точки траектории просматриваются
возможные направления движения в одной и той же
последовательности (например, ВВЕРХ, ВПРАВО, ВНИЗ, ВЛЕВО); шаг
производится в первую обнаруженную свободную соседнюю ячейку;
клетка, в которую сделан шаг отмечается «+»;
2) если из очередной клетки дальше пути нет (тупик), то происходит
возврат на один шаг назад и просматриваются еще не
испробованные пути движения из этой точки; при возвращении
назад, покинутая клетка отмечается пробелом (стирается путь);
3) если очередная клетка, в которую сделан шаг, оказалась на краю
лабиринта (на выходе), то выводим найденный путь.
Выстроим структуру программы, применяя метод последовательной
детализации:




<заголовок программы>
<описание глобальных переменных>
<процедура печати найденного пути PrintL>
<рекурсивная процедура поиска путей Poisk: с места нахождения
путника до края, где каждый путь печатается при помощи процедуры
PrintL >
6
 <основная часть программы: ввод данных и обращение к процедуре
Poisk, задание начальных параметров>
Program Labirint;
Var Lb : array[1..15, 1..15] of char;
m, n, x, y, I, j : byte;
Procedure PrintL; {печать найденного пути}
Var i1, j1 : byte;
Begin
For i1:=1 to m do begin
For j1:=1 to n do write(Lb[i1,j1]);
writeln;
end;
writeln;
end; {конец процедуры печати}
Procedure Poisk(sti, stj: byte);
Begin
If Lb[sti,stj]=’ ‘ {если клетка свободна}
Then begin
Lb[sti,stj] := ‘+’; {отмечаем шаг}
If (sti=1) or (sti=n) or (stj=1) or (stj=m)
then PrintL
{если вышли на край, то печатаем путь}
else begin {поиск следующего шага}
Poisk(sti-1, stj);
Poisk(sti, stj+1);
Poisk(sti+1, stj);
Poisk(sti, stj-1);
end;
Lb[sti,stj]:=’ ‘; {возвращение назад}
end;
End; {конец процедуры поиска}
Begin {основная программа}
{ввод данных}
Readln(m, n);
For i:=1 to m do begin
For j:=1 to n do read( Lb[i,j]);
Readln;
end;
Readln(x,y);
Poisk(x,y);
End.
7
Характеристика метода перебора с возвратом
Метод перебора с возвратом не сложен в изучении и хорош тем, что
выдает все возможные варианты пути. Его всегда можно применить в
решении такого рода задач, внеся некоторые коррективы, если задача
требует рассмотрения дополнительных условий или ограничений. Его можно
доработать, если необходимо печатать, только кратчайший путь
(подсчитывая шаги «+», сравнивая их и запоминая матрицу, которая,
впоследствии, подлежит печати). Но этот метод не является эффективным,
если судить о времени выполнения программы, так как вынуждает
просматривать все варианты. Иногда, формулировка задачи требует
нахождения первого попавшегося варианта или, например, кратчайшего
пути. Тогда встает необходимость поиска другого метода решения.
Другие алгоритмы прохождения лабиринтов
Если задача на прохождение лабиринта сводится к поиску
единственного пути, то применяют другие наиболее скоростные методы.
После проведения социологического опроса среди старшеклассников,
посещающих компьютерные лагеря и постоянно участвующих в областных и
всероссийских олимпиадах по информатике, были выяснены названия этих
методов.
Методы:
1. Поиск в ширину (волновой алгоритм);
2. Поиск в глубину.
Эти методы приемлемы только в ситуациях, когда не стоит проблема
перебора всех путей.
Волновой алгоритм
Задача: «Однажды Джеку Воробью принесли весть, что на одном из
Карибских островов спрятан клад. Клад этот спрятан в пещере и путь к нему
подобен лабиринту. Пирату удалось выкрасть карту лабиринта. И вот,
отважный пират отправился на поиски клада. Продвигаясь по лабиринту, он
заплутал. Волшебный компас показал координаты его расположения и
координаты места, где расположен клад. Помоги Джеку отыскать клад».
8
Решение: требуется написать программу, которая по заданному
описанию лабиринта и указанию начальных и конечных координат путника
напечатает возможный кратчайший путь к кладу.
Формат входных данных:
Первая строка содержит размерность лабиринта, а именно М – число
строк в описании лабиринта, и N – число столбцов (M, N <15). Далее вводится
числовая матрица MxN, содержащая описание лабиринта, где стены
отмечены 1, а проходы - 0. Затем вводятся координаты Джека Воробья
(номер строки и столбца (XS, YS), где он находится в текущий момент) и
координаты, где расположен клад (XF, YF).
Формат выходных данных:
Найти ближайший путь к кладу и напечатать описание лабиринта вместе
с намеченным путем. Начало пути пометить цифрой 2. В местах, где
пролегает путь, выставить цифру 3, а в месте клада – 4. Вывести длину пути.
Суть волнового алгоритма в следующем:
1) Прямая волна. Заводим дополнительную матрицу той же
размерности, что и лабиринт. Помечаем начало пути единицей
(начало волны). Сканируем матрицу лабиринта, заполняя
дополнительную по следующему принципу: находим положение
путника и обкладываем соседние клетки числом на единицу
большим, чем, то на котором он стоит в тех местах, где есть проход и
которые еще не заполнялись. Тем самым, добиваемся того, что волна
разрастается. Отсюда и название «обход в ширину».
2) По окончании сканирования, сравниваем последнее выложенное
число с размерностью матрицы. Если оно достигло размерности, то
клад так и не был найден (т.к. это максимальное количество шагов,
которые допустимо было сделать). В подобном случае программа
прерывает свою работу. Сканирования продолжаем до тех пор, пока
не попадем в клетку с кладом, либо пока не произойдет
принудительное прерывание работы программы.
9
3) Если выход возможен, то начинаем обратную волну. Обратная
волна идет с места клада к началу пути. Отсчет шагов идет в
обратную сторону, начиная с предпоследнего числа, которое было
выложено в прямой волне. Помечаем место клада в лабиринте
числом 4. Опираясь на вспомогательную матрицу, щупаем в какую
сторону шагать (ищем, в соседних клетках первое попавшееся число,
отличающееся от текущего на единицу – делаем обратный шаг,
помечая путь 3 в основном лабиринте). Шагаем до тех пор, пока не
выйдем на начало пути. Помечаем начало пути 2.
4) Выводим матрицу лабиринта с намеченным путем и число шагов.
Program Voln;
Var
XS, YS, XF, YF : Byte;
X, Y, K, M, N : Byte;
Mas, Masm : array [1..15, 1..15] of Byte;
Step: byte;
Procedure Next(Var X, Y : Byte); {поиск клетки, куда возможен шаг}
Begin
If (X <M) and (MasM[X, Y] - MasM[X + 1, Y] = 1) then Begin X := X + 1; Exit; End;
If (X >1) and (MasM[X, Y] - MasM[X - 1, Y] = 1) then Begin X := X - 1; Exit; End;
If (Y <N) and (MasM[X, Y] - MasM[X, Y + 1] = 1) then Begin Y := Y + 1; Exit; End;
If (Y >1) and (MasM[X, Y] - MasM[X, Y - 1] = 1) then Begin Y := Y - 1; Exit; End;
End;
Begin
Writeln(‘введите размерность лабиринта’);
Read(M,N);
Writeln(‘введите лабиринт: 0-проход, 1-стена’);
For X := 1 to M do For Y := 1 to N do read(Mas[X, Y]);
WriteLn('введите координаты Воробья');
ReadLn(XS, YS);
WriteLn('введите координаты клада');
ReadLn(XF, YF);
{если координаты начальной или конечной точек пути выпадают на стену, то
выводится ошибка}
If (Mas[XS, YS] = 1) or (Mas[XF, YF] = 1) then Begin
WriteLn('Компас не исправен!!!');
ReadLn;
Halt; End;
10
{прямая волна}
MasM[XS, YS] := 1;
K := 1;
Repeat
K := K + 1;
For X := 1 to M do For Y := 1 to N do
If MasM[X, Y] = K - 1 then
Begin
If (Y <N) and (MasM[X, Y + 1] = 0) and (Mas[X, Y+1] = 0)
Then MasM[X, Y+1] := K;
If (Y >1) and (MasM[X, Y-1] = 0) and (Mas[X, Y-1] = 0)
Then MasM[X, Y-1] := K;
If (X <M)and (MasM[X+1, Y] = 0) and (Mas[X+1, Y] = 0)
Then MasM[X+1, Y] := K;
If (X >1) and (MasM[X-1, Y] = 0) and (Mas[X-1, Y] = 0)
Then MasM[X-1, Y] := K;
End;
If К = M*N then Begin WriteLn('Клад не достижим!!!'); ReadLn; Halt; End;
Until MasM[XF, YF] >0;
{обратная волна}
K := K - 1; step:=K; X := XF; Y := YF; Mas[XF, YF] := 4;
Repeat
Next(X, Y);
Mas[X, Y] := 3; K := K - 1;
Until (X = XS) and (Y = YS);
Mas[XS, YS] := 2;
{вывод результата}
WriteLn;
For X := 1 to M do Begin
For Y := 1 to N do Write(Mas[X, Y], ' ');
WriteLn;
End;
Writeln;
WriteLn('длина пути: ', step);
ReadLn;
End.
Не смотря на то, что программа волнового алгоритма больше по
объему, время выполнения ее гораздо меньше, т.к. она содержит меньше
итераций. Матрица лабиринта сканируется лишь до определенного момента,
11
поэтому результат достигается быстро. Минус этого приема в том, что метод
не дает возможности вывести все пути (это достижимо только переборным
способом).
Копилка задач
1. Шарик в лабиринте
В игре «Шарик в лабиринте» необходимо провести шарик по
пластмассовому лабиринту. Для этого лабиринт можно наклонять, отчего
шарик начинает катиться по проходу с ускорением g = 9,811 м/с2. Шарик
катится строго параллельно сторонам лабиринта, по прямой. На поворотах
шарик мгновенно и полностью останавливается. Лабиринт имеет размер N x
N см (1 <= N <= 10) и высоту 1 см и состоит из клеток — кубиков 1 x 1 x 1 см.
Каждый такой кубик является либо проходом, либо стенкой. Ровно один из
кубиков помечен как выход из лабиринта. Требуется определить
минимальное время, за которое шарик можно перекатить из левого
верхнего угла лабиринта к выходу.
Примечание: путь, пройденный равноускоренно движущимся из
состояния покоя телом за время t, равен g*t2/2.
Описание лабиринта состоит из N строк. Каждая строка описания
состоит из N цифр от 0 до 2, разделённых пробелами. Здесь 0 соответствует
пустой клетке, 1 — стенке, 2 — выходу. При этом цифра 2 встречается во всем
описании ровно один раз, а первая цифра первой строки не равна 1.
Решение:
Решение задачи сводится к нахождению кратчайшего пути в лабиринте,
чего можно достигнуть методом перебора с возвратом. Затем используя
формулу, указанную в пояснении, вычислить время движения.
2. Кинг Конг
До крыши Эмпайр Стейт Билдинг Джек должен преодолеть N-1
лестничных пролетов, причем известно, за какое время можно пробежать
каждый из них. Также в здании находится лифт; для любого пролета между
соседними этажами известно, какое время требуется лифту, чтобы проехать
его. Чтобы войти в лифт, выйти из него или нажать кнопку требуется 0
секунд. Также за 0 секунд можно зайти в лифт, нажать кнопку нужного этажа,
тут же выйти из него и побежать наверх. Можно останавливаться на этажах,
12
чтобы подождать лифт. Изначально лифт находится на первом этаже, там же,
где стоит Джек. Написать программу для нахождения наименьшего времени,
которое нужно для подъема до самого верхнего этажа.
Первая строка содержит целое число N – количество этажей Эмпайр
Стейт Билдинг (1 ≤ N ≤ 1000). Вторая строка содержит N-1 целых чисел xi (1 ≤
xi ≤ 1000); xi – время в минутах, которое потребуется Джеку, чтобы
преодолеть i-й пролет пешком. Третья строка содержит N-1 целых чисел yi (1
≤ yi ≤ 1000); yi – время в минутах, которое потребуется лифту, чтобы
преодолеть i-й пролет.
Решение:
В этой задаче, хоть и не явно, но прослеживается своеобразный
лабиринт. Путь, в котором прокладывается через элементы двух линейных
массивов.
Решение задачи сводится к тому, чтобы определить минимальную
сумму N-1 элемента из двух одномерных массивов. Этого можно достичь,
применяя метод перебора с возвратом, выбирая минимальную сумму.
3. Лабиринты и монстры.
Два монстра помещаются в лабиринт размера NxN. Хороший монстр
помещается в левый верхний угол лабиринта, а плохой - в правый нижний.
Каждая клетка лабиринта содержит либо цифру 0 либо 1. Монстры могут
ходить только по клеткам, в которых записана цифра 1. Хороший монстр
может двигаться только вправо или вниз. Плохой монстр может двигаться
только влево или вверх. Каждый ход оба монстра обязаны сделать ровно 1
шаг, т.е. они не могут стоять на месте. Вам необходимо определить такой
путь для каждого монстра, чтобы они встретились.
В первой строке записано число N (1<=N<=10) - размер лабиринта. В
следующих N строках записан сам лабиринт, по N символов в каждой строке.
Решение:
В этой задаче необходимо искать одновременно два пути, продвигаясь
в двух направлениях к намеченной цели. Достигнув цели, следует
осуществить проверку условия, что длины путей совпадают. Если длины не
совпадают, нужно делать откатку назад и искать другие пути. Опять-таки,
очевиден переборный алгоритм. Классическую программу можно просто
откорректировать.
13
4. Кратчайший путь в лабиринте
Задан лабиринт из n комнат, у каждой из которых имеется не менее
одной и не более трех дверей, соединяющих между собой различные
комнаты. Одна из комнат – вход, другая – выход. Найти кратчайший путь от
входа к выходу.
Решение:
При поиске используется стандартный алгоритм волны на графе.
Вершинами графа являются комнаты лабиринта, а ребрами – двери.
5. Выход из лабиринта
Во время торнадо в Костромской области было повалено большое
количество деревьев. Однажды утром, спустя пару дней после торнадо,
мальчик Вася вышел прогуляться и увидел, что поваленные деревья
образовали настоящий лабиринт. Вася очень обрадовался, стал гулять и
играть в лабиринте. Внезапно ему позвонила мама и велела срочно
прибежать домой. Вася был послушным мальчиком и, конечно же, хотел
попасть домой как можно скорее, чтобы не огорчить маму, но и побродить
по лабиринту ему тоже очень хотелось. Помогите ему узнать, как быстро он
сможет добраться до дома.
Входные данные:
Первая строка содержит целые положительные числа N, M (N,M <=1000) –
размерность матрицы лабиринта. Далее следует ввод матрицы,
описывающей лабиринт (0 – проход, 1 - дерево). После следуют целые
положительные числа x1, y1, x2, y2 – координаты Васи и выхода из
лабиринта (числа не превышают размеров матрицы).
Выходные данные: единственное число – длина кратчайшего пути от
точки (x1, y1) до точки (x2, y2), если выход из лабиринта существует, и -1 в
противном случае.
Решение: при поиске можно использовать стандартный алгоритм
волны.
6. Лабиринт с тигром
В средние века в замках Европы был популярен следующий вид казни: в
лабиринт, в котором находился тигр, заводили раба. Рабу была известна
карта лабиринта и его первоначальное расположение. Тигр обладал очень
тонким обонянием, то есть он знал, где находится раб в любой момент
времени и мог в кратчайшее время настигнуть раба, если мог.
14
Дана схема лабиринта в виде таблицы NхM. Вход в лабиринт находится
в левой верхней клетке. В этом же месте находится раб в начальный момент
времени. Выход из лабиринта находится в правой нижней клетке.
Гарантируется, что от входа до выхода существует путь и что тигр может за
конечное время добраться до входа в лабиринт. Также известно, что
лабиринт ограничен сплошной стеной по периметру.
Необходимо определить, сможет ли раб добраться до выхода, если за
единицу времени как раб, так и тигр, могут переместиться на одну клетку в
свободном направлении (то есть туда, где нет стены).
Входные данные:
Первая строка содержит два числа: N и M – длина и ширина лабиринта
(4 <= N, M <= 1000). Далее следует описание лабиринта. Символ «#» означает
стену, а пробел - свободное пространство, «T» - положение тигра в
начальный момент времени.
Выходные данные:
Выведите «Yes», если раб успеет добраться до выхода, и «No», если раб
будет съеден тигром.
7. Осмотр лабиринта
Разведывательный робот предназначен для исследования опасных
лабиринтов. Лабиринт, как обычно, представляет собой прямоугольник
размером MхN, состоящий из одинаковых квадратов единичного размера.
Некоторые квадраты заняты стенами, остальные свободны. Робот может
перемещаться по горизонтали или по вертикали, если этому не препятствуют
стены. Кроме того, робот снабжён четырьмя видеокамерами, которые
позволяют ему видеть все квадраты лабиринта до ближайшей стены по
горизонтали и по вертикали. Робот перемещается по лабиринту в
соответствии с заданной ему программой. Программа для робота – это
последовательность команд R, L, U, D. Команда R означает переместиться на
один квадрат вправо, команда L – переместиться на один квадрат влево, U –
на один квадрат вверх, и команда D – на один квадрат вниз. Если робот не
может выполнить какую-либо команду (соответствующий квадрат занят
стеной), то он пропускает эту команду и переходит к следующей. Ваша
задача – по заданному плану лабиринта и заданной программе для робота
подсчитать количество невыполненных команд и количество квадратов,
15
осмотренных роботом. Квадрат, в котором находится робот в данный
момент, ему не виден.
Входные данные:
В первой строке записаны два целых числа N и M – размер лабиринта по
вертикали и по горизонтали (3 <= N, M <= 100). Далее следует матрица
лабиринта: пробел - свободные квадраты, ‘#’ – квадраты, занятые стенами, и
символ ‘+’ (который встречается в плане лабиринта ровно один раз) –
начальное положение робота. Лабиринт всегда со всех сторон окружён
стенами, так что робот не может выйти за его пределы. В следующей строке
целое число L – длина программы для робота (1 <= L <= 10000). И в
последней строке записана программа для робота. Программа состоит
только из символов ‘R’, ‘L’, ‘U’, ‘D’.
Выходные данные:
Два целых числа через пробел – количество команд, которые робот не
смог выполнить и количество квадратов, которые он осмотрел.
8. «Левый лабиринт»
В спортзале размером NxM метров построили современный аттракцион
под названием «Левый лабиринт». Для этого на полу спортзала с интервалом
в 1 метр начертили линии, параллельные стенам спортзала. Таким образом,
спортзал разбили на NxM клеток. Дальше некоторые из этих клеток
покрасили в черный цвет.
Аттракцион заключается в том, что участника ставят в некоторой клетке
спортзала и просят как можно быстрее добежать до некоторой другой
клетки. При этом накладываются следующие условия:
Участнику запрещено ходить по черным клеткам.
Придя в какую-то клетку, участник может пойти либо прямо, либо
налево, либо направо (если в соответствующем направлении клетка не
покрашена в черный цвет): ходить назад, а также ходить по диагонали
запрещается.
За все время пути участнику разрешается повернуть направо (то есть
пойти из текущей клетки направо относительно того, откуда он пришел в
данную клетку) не более K раз.
16
В начальной клетке участник может встать лицом в ту сторону, в какую
ему захочется. С какой стороны участник прибежит в конечную клетку также
не важно.
Известно, что на то, чтобы перебежать из клетки в соседнюю, участник
тратит ровно 1 секунду. Требуется вычислить минимальное время, за
которое участник сможет достичь конечной клетки.
Входные данные:
Сначала вводится число K — количество разрешенных поворотов
направо (целое число из диапазона от 0 до 5), затем записаны числа N и M,
задающие размеры спортзала — натуральные числа, не превышающие 20.
Далее следует описание лабиринта. Число 0 обозначает неокрашенную
клетку, число 1 — покрашенную, число 2 — клетку, откуда стартует участник
и число 3 — клетку, куда нужно добежать (клетки, помеченные 2 и 3,
являются неокрашенными). В лабиринте всегда есть ровно одна начальная
клетка и ровно одна клетка, в которую нужно попасть.
Выходные данные:
Выведите минимальное время, за которое можно добраться в конечную
клетку. Если попасть в конечную клетку с соблюдением всех условий нельзя,
выведите –1.
Решение: при поиске используется стандартный алгоритм волны с
добавлением дополнительных условий.
17
Заключение.
Работая над проектом, автор следовал согласно намеченному плану,
который изложен в вводной части работы (список задач проекта).
Поставленная цель достигнута, но не в совершенстве. У работы есть
перспектива. Можно добавить рассмотрение метода обхода в глубину.
Кроме всего прочего, в работе не рассматриваются задачи, где лабиринт
может быть представлен графом, хотя в «копилке» задач присутствует
подобная задача. Работу можно пополнить разбором задач, описанных в
«копилке». А также добавить новые задачи.
Представленная работа может оказаться полезной для подготовки к
кружковым занятиям по программированию в старших классах, а также, для
подготовки к олимпиадам.
Список используемой литературы:
1. И.Г. Семакин Лекции по программированию, Пермь, 1996
2. http://ru.wikipedia.org
3. П.В.Пшеничный, Р.Р.Тагиров Анализ и построение вычислительных
алгоритмов (на примерах олимпиадных задач по
программированию) Методическое пособие, Казань, 2009
4. Е.В. Касьянова, С.Н.Касьянова Программирование для школьников:
сборник задач повышенной сложности с решениями, Новосибирск,
2002
18
Download