迷宫
(maze.pas/c/cpp)
【问题描述】
电脑游戏中有许多令人头疼的迷宫,会花费玩家相当多的时间,你通过秘笈获得了游戏迷宫的地图,你希望找到最短的一条走出迷宫的道路,并且想知道一共有多少条最短的道路,但是由于地图非常庞大,所以你不能在短时间找出这些道路,因此,你需要编写一个程序来找出这些最短的道路,并且统计一下一共有多少条这样的道路。
例如,对于下图所示的迷宫:
|
|
|
S |
|
X |
X |
|
|
X |
X |
|
E |
|
|
|
X表示障碍物,不可以通过,S表示迷宫的入口,E表示迷宫的出口。显然,从入口到出口至少需要走6步,而长度为6的道路一共有两条。
【输入文件】
输入文件maze.in,第一行是一个整数n(1 ≤n ≤ 25),表示迷宫是一个n×n的矩阵。以下n行每行有n个字符来描述地图,“.”表示可以通过,“X”表示不可以通过,“S”表示迷宫的入口,“E”表示迷宫的出口。(注意:所有的字母均为大写)。
【输出文件】
输出文件maze.out包括两行,第一行包含一个整数,表示从入口到出口走的最短距离。第二行包含一个整数,表示最短路径的调数,答案保证小于231。
【样例输入】
4
…S
.XX.
.XX.
E...
【样例输出】
6
2
最容易想到深搜,但是一看数据范围,就放弃了(不过也写了深搜,可以保证正确,后面可以对拍)
接着就是动规递推了,用 f[t,x,y]表示当前第 t 步走到坐标(x,y)的方案数并且 t<=n2
f[t,x,y] = f[t,x,y]+{f[t-1,x+1,y]+...}上下左右四个点
Pascal Code
program maze;
const
dx:array[1..4] of longint=(0,0,1,-1);
dy:array[1..4] of longint=(1,-1,0,0);
var
n:longint;
ex,ey,sx,sy:longint;
f:array[0..25*25+10,0..50,0..50] of longint;
map:array[0..50,0..50] of longint;
procedure init;
begin
assign(input,'maze.in');
assign(output,'maze.out');
reset(input);
rewrite(output);
end;
procedure outit;
begin
close(input);
close(output);
halt;
end;
procedure readdata;
var
i,j:longint;
ch:char;
begin
read(n);readln;
fillchar(map,sizeof(map),255);
for i:=1 to n do
begin
for j:=1 to n do
begin
read(ch);
if ch<>'X' then map[i,j]:=0;
if ch='S' then
begin
sx:=i;sy:=j;
end;
if ch='E' then
begin
ex:=i;ey:=j;
end;
end;
readln;//跳行
end;
end;
procedure main;
var
i,j,k,t:longint;
begin
fillchar(f,sizeof(f),0);
f[0,sx,sy]:=1;
for t:=1 to n*n do
begin
fillchar(f[t],sizeof(f[t]),0);
for i:=1 to n do
for j:=1 to n do
if map[i,j]=0 then
for k:=1 to 4 do
if map[i+dx[k],j+dy[k]]=0 then
f[t,i,j]:=f[t,i,j]+f[t-1,i+dx[k],j+dy[k]];
if f[t,ex,ey]<>0 then
begin
writeln(t);
break;
end;
end;
writeln(f[t,ex,ey]);
end;
begin
init;
readdata;
main;
outit;
end.