
- •Олимпиадные задачи и решения
- •Векторы (100 баллов)
- •Погодные условия (100 баллов)
- •Шоколадные плитки (100 баллов)
- •Работники (100 баллов)
- •Робот (100 баллов)
- •Зал Круглых Столов (100 баллов)
- •Вто (100 баллов)
- •Вишня (100 баллов)
- •Алхимия (100 баллов)
- •Цепь (100 баллов)
- •Казино (100 баллов)
- •Система уравнений (100 баллов)
- •Забавный конфуз
- •Соревнование
- •Абракадабра
- •Циферблат
- •Многоугольники
- •Квадрат
- •Лабиринт
- •Задача “Шифр”
- •Задача “Школы”
- •Последовательность
- •Автобус
- •Головоломка
- •Электронная почта
- •Виртуляндия
- •Конвейер
- •Новости
Лабиринт
Чтобы добраться до источника живой воды, путешественник должен пройти через лабиринт. Не всегда существует путь к источнику, но путешественник может проходить сквозь стены, используя магию. К сожалению, путешественник может использовать магию только ограниченное количество раз, а до источника необходимо добраться как можно быстрее.
Лабиринт имеет форму квадрата, который состоит из NN квадратных клеток, внутри которого вдоль сторон клеток могут быть расположены стены.
В каждый момент времени путешественник может находиться в одной и только в одной клетке лабиринта.
Одним ходом считается перемещение путешественника в соседнюю по горизонтали или по вертикали клетку. Путешественник может K раз проходить сквозь стену и не может выходить за пределы лабиринта.
Задание Составьте программу MAZE, которая вычислит минимальное количество ходов, за которое путешественник может добраться до источника с координатами (P, Q), начав путь в клетке с координатами (1, 1).
Входные данные Входной текстовый файл MAZE.DAT в первой строке содержит числа N, K, P, Q (2N200, 0K250, 1P,QN). Следующие N-1 строк содержат по N целых чисел — признаков наличия горизонтальных стен между клетками. Следующие N строк содержат N-1 целых чисел — признаков наличия вертикальных стен между клетками. 0 означает отсутствие стены, 1 – присутствие.
Пример входного файла
3 1 2 3 0 0 0
0 1 0
1 0
1 0
0 0
Выходные данные Единственная строка выходного текстового файла MAZE.SOL должна содержать найденное минимальное количество ходов, или число –1, если путь найти не удалось
Пример выходного файла 3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{$A-,B-,D-,E+,F-,G-,I+,L-,N+,O-,P-,Q+,R-,S-,T-,V+,X+,Y+}
{$M 16384,0,655360}
program Maze;
const
MaxN = 200;
type
tArr = array [1..MaxN, 1..MaxN] of byte;
pArr = ^tArr;
tPlainArr = array [0..MaxN*MaxN+100] of byte;
pPlainArr = ^tPlainArr;
var fr,fw:text;
n,k,x,y:integer;
H,V:pArr;
ma: tArr;
qx,qy:pPlainArr; {QueueX, QueueY - x and y coordinate of each maze's cell in
the queue, we stand in}
qb, qe: word; {Queue pointers to the beginning and the end of the data}
qm : word; {queue pointer to the last cell coordinates with current
prepared move - move delimiter}
qLength: word;
procedure PopQ(var x,y:byte);
begin
inc(qe);
if qe=qLength then qe:=0;
x:=qx^[qe]; y:=qy^[qe];
end;
procedure PushQ(x,y:byte);
begin
inc(qb);
if qb=qLength then qb:=0;
qx^[qb]:=x; qy^[qb]:=y;
end;
procedure Make;
var cx,cy,ck:byte;
cm:integer;
begin
qLength := word(n)*n+100; {maximal cells' count in the queue
+ 100 'na vsyakiy sluchai' :-) }
GetMem(qx, qLength);
GetMem(qy, qLength);
{queue initialization}
qb:=1; qe:=0;
qx^[1]:=1; qy^[1]:=1;
FillChar(ma, MaxN*MaxN, 255);
ma[1,1] := 0;
cm:=0; {move's counter}
qm:=1;
{while the queue is not empty or until we have find the result}
while (qb<>qe) do
begin
PopQ(cx, cy);
ck:=ma[cx,cy];
{generate ordinal moves first}
if (cx>1) and (H^[cx-1,cy]=0) and ( (ma[cx-1,cy]=255)or(ma[cx-1,cy]>ck) ) then
begin
PushQ(cx-1,cy);
ma[cx-1,cy]:=ck;
end;
if (cx<n) and (H^[cx,cy]=0) and ( (ma[cx+1,cy]=255)or(ma[cx+1,cy]>ck) ) then
begin
PushQ(cx+1,cy);
ma[cx+1,cy]:=ck;
end;
if (cy>1) and (V^[cx,cy-1]=0) and ( (ma[cx,cy-1]=255)or(ma[cx,cy-1]>ck) ) then
begin
PushQ(cx,cy-1);
ma[cx,cy-1]:=ck;
end;
if (cy<n) and (V^[cx,cy]=0) and ( (ma[cx,cy+1]=255)or(ma[cx,cy+1]>ck) ) then
begin
PushQ(cx,cy+1);
ma[cx,cy+1]:=ck;
end;
{generate magic moves last}
if (cx>1) and (H^[cx-1,cy]=1) and (ck<k) and
( (ma[cx-1,cy]=255)or(ma[cx-1,cy]>ck) ) then
begin
PushQ(cx-1,cy);
ma[cx-1,cy]:=ck+1;
end;
if (cx<n) and (H^[cx,cy]=1) and (ck<k) and
( (ma[cx+1,cy]=255)or(ma[cx+1,cy]>ck) ) then
begin
PushQ(cx+1,cy);
ma[cx+1,cy]:=ck+1;
end;
if (cy>1) and (V^[cx,cy-1]=1) and (ck<k) and
( (ma[cx,cy-1]=255)or(ma[cx,cy-1]>ck) ) then
begin
PushQ(cx,cy-1);
ma[cx,cy-1]:=ck+1;
end;
if (cy<n) and (V^[cx,cy]=1) and (ck<k) and
( (ma[cx,cy+1]=255)or(ma[cx,cy+1]>ck) ) then
begin
PushQ(cx,cy+1);
ma[cx,cy+1]:=ck+1;
end;
if qe=qm then
begin
inc(cm);
qm:=qb;
if ma[x,y]<>255 then break;
end;
end;
if ma[x,y]=255 then writeln(fw, '-1')
else writeln(fw, cm);
FreeMem(qy,qLength);
FreeMem(qx,qLength);
end;
var
i,j:integer;
begin
GetMem(H, MaxN*MaxN);
GetMem(V, MaxN*MaxN);
assign(fr, 'maze.dat');
reset(fr);
assign(fw, 'maze.sol');
rewrite(fw);
readln(fr, n, k, x, y);
for i:=1 to n-1 do
for j:=1 to n do
read(fr, H^[i,j]);
for i:=1 to n do
for j:=1 to n-1 do
read(fr, V^[i,j]);
if (x=1)and(y=1) then writeln(fw,'0')
else Make;
close(fw);
close(fr);
FreeMem(V, MaxN*MaxN);
FreeMem(H, MaxN*MaxN);
end.