一开始我用深搜,查到一个更新一个点,结果。。。。。。炸了。两个AC,其他全是TLE。所以深搜害人不深啊。
我后来还是用回了宽搜。
宽搜很简单,先有定义头指针ltop和尾指针rtop,和判断这个位置有没有走过的bz,还有一个队列a[1..400,1..3]。a[i,1]记录x坐标,a[i,2]记录y坐标,a[i,3]记录第几步。
主要部分思路如下
一开始尾指针inc(rtop),从a[top,1],a[top,2]开始发展,如果可以走(走了之后不超范围并且没走过)就inc(ltop)和更新a[ltop],然后在接着inc(rtop),直到ltop小于rtop,就可以退出循环,输出了。因为此时已经没有任何可能性可以发展了。
代码如下:
var
fx:array[1..8,1..2]of longint=((1,2),(2,1),(-1,2),(-2,1),(1,-2),(2,-1),(-1,-2),(-2,-1));
bz:array[1..400,1..400] of boolean;
a:array[1..100000,1..3] of longint;
f:array[0..401,0..401] of longint;
i,j,x,y,n,m,ltop,rtop:longint;
begin
fillchar(f,sizeof(f),$FF);
fillchar(bz,sizeof(bz),1);
read(n,m,x,y);
f[x,y]:=0;
bz[x,y]:=false;
a[1,1]:=x;
a[1,2]:=y;
a[1,3]:=0;
ltop:=1;
while ltop>rtop do
begin
inc(rtop);
for i:=1 to 8 do
if (a[rtop,1]+fx[i,1]<=n) and (a[rtop,1]+fx[i,1]>0) and (a[rtop,2]+fx[i,2]<=m) and (a[rtop,2]+fx[i,2]>0) and bz[a[rtop,1]+fx[i,1],a[rtop,2]+fx[i,2]] then
begin
inc(ltop);
a[ltop,1]:=a[rtop,1]+fx[i,1];
a[ltop,2]:=a[rtop,2]+fx[i,2];
a[ltop,3]:=a[rtop,3]+1;
f[a[ltop,1],a[ltop,2]]:=a[ltop,3];
bz[a[ltop,1],a[ltop,2]]:=false;
end;
end;
for i:=1 to n do
begin
for j:=1 to m do
begin
write(f[i,j]);
if (f[i,j]<10) and (f[i,j]>=0) then write(' ');
if ((f[i,j]<100) and (f[i,j]>=10)) or (f[i,j]=-1) then write(' ');
if (f[i,j]<1000) and (f[i,j]>=100) then write(' ');
if (f[i,j]>=1000) then write(' ');
end;
writeln;
end;
end.