【动规递推】【120718测试】【NOIP模拟题】迷宫
迷宫
(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.
..... 转载请注明出处 ..... http://oijzh.cnblogs.com ..... by jiangzh