题目来源:POJ2435

分析

题目大意:

给一张各种字符组成的图,

S,E分别为起点终点

+是十字路口

-,|是横的竖的街道

.不能走

1
2
3
4
5
6
7
8
9
+-+-+.+-+-+

|...|.....|

+-+.+-+-+-+

..|.......|

S-+-+-+.E-+

比如这张图

现在要求是输出从起点到终点的最短路径

路径表示为

dir tot

dir 表示走的方向 用 E,W,S,N表示

tot 表示向这个方向走tot个十字路口

解法

很显然是广搜,从起点广搜到终点,way[]记录过来的点和方向

然后从终点dfs回去,如果该点的way[],也就是来的方向和last不一样,就说明这是个拐点

如果同时是拐点且为十字路口,那么在回溯的时候把路径输出

优化

详解

回溯的时候用sum记录从上一个输出的点到现在过了几个十字路口

细节

注意”-“和”|”只能扩展两个方向,而十字路口和S,E可以扩展四个方向

源程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
Program Lwx;
Const mv:array[1..4, 1..2] of longint=((1, 0),(-1, 0),(0, 1),(0,- 1));
ba:array[1..4] of char=('S', 'N', 'E', 'W');
Var n, m:longint;
map:array[1..100] of string;
way:array[1..100, 1..100, 1..3] of longint;
get:array[1..100, 1..100] of longint;
fns:array[1..100000, 1..2] of longint;
i, j, k, l, a, b, x, y, z, sx, sy, ex, ey:longint;

Procedure dfs(x, y, g:longint);
Var a, b, c, d:longint;
Begin
if (x = sx)and(y = sy) then
begin
k := 0;
exit;
end;
if way[x, y, 3] <> g then d := 1 else d := 0;
dfs(way[x, y, 1], way[x, y, 2], way[x, y, 3]);
if (map[x, y] = '+')or(map[x, y] = 'E') then
begin
k := k + 1;
if d = 1 then
begin
writeln(ba[way[x, y, 3]], ' ', k);
k := 0;
end;
end;
End;

Begin
assign(input, 'test.in'); reset(input);
readln(n, m);
for i := 1 to n*2-1 do
begin
readln(map[i]);
for j := 1 to m*2-1 do
begin
if map[i, j] = 'S' then
begin
sx := i;
sy := j;
end;
if map[i, j] = 'E' then
begin
ex := i;
ey := j;
end;
end;
end;
close(input);
fillchar(get, sizeof(get), $ff);
get[sx, sy] := 0;
fns[1, 1] := sx;
fns[1, 2] := sy;
i := 0; j := 1;
while i < j do
begin
x := fns[i+1, 1];
y := fns[i+1, 2];
for k := 1 to 4 do
begin
if (map[x, y] = '|')and(k >= 3) then continue;
if (map[x, y] = '-')and(k <= 2) then continue;
a := x + mv[k, 1];
b := y + mv[k, 2];
if (a < 1)or(a > n*2-1)or(b < 1)or(b > m*2-1) then continue;
if map[a, b] = '.' then continue;
if get[a, b] = -1 then
begin
get[a, b] := get[x, y] + 1;
way[a, b, 1] := x;
way[a, b, 2] := y;
way[a, b, 3] := k;
inc(j);
fns[j, 1] := a;
fns[j, 2] := b;
end;
end;
inc(i);
end;
dfs(ex, ey, 0);
End.