马的遍历
问题描述
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步
分析
一看就是广搜,每走过一个点就标记,标记过的不走,起点标记为走过,不用把每个点当成终点做n*m次bfs,每个点遍历一次即可。(最后输出是按长度输出)
时间复杂度
O(n)
代码
const
maxn=10000;
dx:array[1..8] of integer=(-2,-1,1,2,2,1,-1,-2);
dy:array[1..8] of integer=(1,2,2,1,-1,-2,-2,-1);
var
a:array[0..400,0..400] of longint;
s:array[0..maxn,1..3] of longint;
f:array[0..400,0..400] of boolean;
qx,qy,m,n,i,j,k:longint;
st:string;
function check(x,y:longint):boolean;
begin
check:=true;
if (x<1) or (x>n) or (y<1) or (y>m) or (f[x,y]) then exit(false);
end;
procedure bfs;
var
i,h,t,zx,zy:longint;
begin
h:=0;t:=1;
s[1,1]:=qx;
s[1,2]:=qy;
while h<t do
begin
inc(h);
for i:=1 to 8 do
begin
zx:=s[h,1]+dx[i];
zy:=s[h,2]+dy[i];
if check(zx,zy) then
begin
inc(t);
f[zx,zy]:=true;
s[t,1]:=zx;
s[t,2]:=zy;
s[t,3]:=s[h,3]+1;
a[zx,zy]:=s[t,3];
end;
end;
end;
end;
begin
readln(n,m,qx,qy);
for i:=1 to n do
for j:=1 to m do
a[i,j]:=maxlongint;
a[qx,qy]:=0;
f[qx,qy]:=true;
bfs;
for i:=1 to n do
for j:=1 to m do
if a[i,j]=maxlongint then a[i,j]:=-1;
for i:=1 to n do
begin
for j:=1 to m do
begin
str(a[i,j],st);
write(st,'':5-length(st));
end;
writeln;
end;
end.