最少转弯问题

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

【输入格式】

行:n  m

n+1行:整个地图地形描述(0:空地;1:高山),

如(图1)第行地形描述为:1 0 0 0 0 1 0 

行地形描述为:0 0 1 0 1 0 0

……

n+2 行:x1 y1 x2 y2 (分别为起点、终点坐标)

【输出格式】

(即最少的拐弯次数)

【输入输出样例】(见图1):

最少转弯问题   最少转弯问题

【解题思路】

这是一只宽搜的经典题目,过程不多讲,一定要判断初始方向,不能一开始就转向,刚开始就错在这了。

 1 program t4;
 2 const fx:array[1..4] of longint=(0,1,0,-1);
 3        fy:array[1..4] of longint=(-1,0,1,0);
 4 var dt:array[1..100000,1..2] of longint;
 5     d,ans:array[1..100000] of longint;
 6     f:array[1..100,1..100] of longint;
 7     pd:array[1..100,1..100] of longint;
 8     x1,x2,y1,y2,i,j,h,t,sum,n,m:Longint;
 9 begin
10     filldword(pd,sizeof(pd) div 4,maxlongint div 2);
11     read(n,m);
12     for i:=1 to n do
13         for j:=1 to m do read(f[i,j]);
14     read(x1,y1,x2,y2);
15     for i:=1 to 4 do
16     begin
17         if (x1+fx[i]>0) and(x1+fx[i]<=n) and(y1+fy[i]>0) and (y1+fy[i]<=n)
18         and(f[x1+fx[i],y1+fy[i]]=0) then//重点在这
19         begin
20             inc(t);
21             dt[t,1]:=x1;
22             dt[t,2]:=y1;
23             d[t]:=i;
24         end;
25     end;
26     while h<=t do
27     begin
28         inc(h);
29         sum:=1;
30         while (dt[h,1]+fx[d[h]]*sum>0) and (dt[h,2]+fy[d[h]]*sum>0)
31            and (dt[h,1]+fx[d[h]]*sum<=n) and (dt[h,2]+fy[d[h]]*sum<=m)
32            and (f[dt[h,1]+fx[d[h]]*sum,dt[h,2]+fy[d[h]]*sum]<>1)
33            //and (not pd[dt[h,1]+fx[d[h]]*sum,dt[h,2]+fy[d[h]]*sum])
34            do
35            begin
36                 inc(t);
37                 dt[t,1]:=dt[h,1]+fx[d[h]]*sum;
38                 dt[t,2]:=dt[h,2]+fy[d[h]]*sum;
39                 d[t]:=d[h];
40                 ans[t]:=ans[h];
41 ',dt[h,2]+fy[d[h]]*sum,' ',ans[t]);
42                 if (dt[h,1]+fx[d[h]]*sum=x2)and(dt[h,2]+fy[d[h]]*sum=y2) then
43                 begin
44                     writeln(ans[h]);
45                     halt;
46                 end;
47                 inc(sum);
48            end;
49            for i:=1 to 4 do
50             if i mod 2<>d[h] mod 2 then
51             begin
52                 if (dt[h,1]+fx[i]>0) and (dt[h,2]+fy[i]>0) and
53                 (dt[h,1]+fx[i]<=n) and (dt[h,2]+fy[i]<=m) and
54                 (f[dt[h,1]+fx[i],dt[h,2]+fy[i]]<>1)
55                 then
56                 begin
57                     inc(t);
58                     dt[t,1]:=dt[h,1]+fx[i];
59                     dt[t,2]:=dt[h,2]+fy[i];
60                     d[t]:=i;
61                     ans[t]:=ans[h]+1;
62                     //writeln(dt[h,1]+fx[i],' ',dt[h,2]+fy[i],' ',ans[t]);
63                     if (dt[h,1]+fx[i]=x2)and(dt[h,2]+fy[i] =y2) then
64                 begin
65                     writeln(ans[t]);
66                     halt;
67                 end;
68                 end;
69             end;
70 
71     end;
72 end.