最少转弯问题

Description

给出一张地图,这张地图被分为n×m(n,m<=100)个方块,任何一个方块不是平地就是高山。平地可以通过,高山则不能。现在你处在地图的(x1,y1)这块平地,问:你至少需要拐几个弯才能到达目的地(x2,y2)?你只能沿着水平和垂直方向的平地上行进,拐弯次数就等于行进方向的改变(从水平到垂直或从垂直到水平)的次数。例如:如图1,最少的拐弯次数为5。

Input

第1 行:n m
第2 至n+1行:整个地图地形描述(0:空地;1:高山),
如(图1)
第2 行地形描述为:1 0 0 0 0 1 0
第3 行地形描述为:0 0 1 0 1 0 0
……
第n+2 行:x1 y1 x2 y2 (分别为起点、终点坐标)

Output

s (即最少的拐弯次数)

Sample Input

5 7
1 0 0 0 0 1 0
0 0 1 0 1 0 0
0 0 0 0 1 0 1
0 1 1 0 0 0 0
0 0 0 0 1 1 0
1 3 1 7

Sample Output

5

程序:

const
dx:array[1..4]of longint=(1,-1,0,0);
dy:array[1..4]of longint=(0,0,-1,1);

var
r,c,e1,e2,b1,b2:longint;
a:array[0..501,0..501]of longint;
f:array[0..250001]of longint;
s:array[0..250001,1..3]of longint;

procedure init;
var
ch:char;
i,j:longint;
begin
    readln(r,c);
    for i:=1 to r do
    begin
        for j:=1 to c do
        read(a[i,j]); 
        readln;
    end;
    read(b1,b2,e1,e2);
end;

function ping(x,y:longint):boolean;
begin
    if (x<1)or(x>r)or(y<1)or(y>c)then exit(true);
    if a[x,y]=1 then exit(true);
    exit(false);
end;

procedure bfs;
var
h,t,i,l:longint;
begin
    h:=0;t:=1;f[1]:=0;
    s[1,1]:=b1;s[1,2]:=b2;
    repeat
         inc(h);
         for i:=1 to 4 do
         if not ping(s[h,1]+dx[i],s[h,2]+dy[i]) then
         begin
             l:=h;
             while not ping(s[l,1]+dx[i],s[l,2]+dy[i]) do
             begin
                 inc(t);
                 s[t,1]:=s[l,1]+dx[i];
                 s[t,2]:=s[l,2]+dy[i];
                 s[t,3]:=s[h,3];
                 a[s[t,1],s[t,2]]:=1;
                 if (s[t,1]=e1)and(s[t,2]=e2)then
                 begin
                     writeln(s[t,3]);
                     exit;
                 end;
                 l:=t;
                 inc(s[t,3]);
             end;
         end;
    until h=t;
end;


begin
    init;
    bfs;
end.

原文地址:https://www.cnblogs.com/YYC-0304/p/9500076.html