题目地址:http://codevs.cn/problem/1026/
分析:
常规的宽搜,每个方向上都一路走到’X‘为止
如果不加以判重,理论上是对的,但是会做大量无用的计算,要么超时要么数组越界,只能得30分
不过,这里的判重并不是指每个点只能经过一次,而是指在一层搜索中,每个点只能经过一次,搜索下一层时,判重数组要清空
代码:
type node=record
x,y,d:longint;
end;
var r,c,n,i,j,cen:longint;
t:string;
hash:array[0..51,0..51] of boolean;//判重数组
map:array[0..51,0..51] of char;
dir:array[1..3000] of longint;
a:array[1..1000000] of node;//宽搜队列
procedure bfs;
var l,r,i:longint;
begin
l:=0;
r:=1;
while l<r do
begin
inc(l);
if a[l].d<>cen then//如果进入下一层搜索判重数组就清空
begin
fillchar(hash,sizeof(hash),true);
cen:=a[l].d;//层数加一
end;
case dir[a[l].d] of
1://北
begin
i:=1;
while map[a[l].x-i,a[l].y]<>'X' do
begin
if a[l].d=n then//如果是最后一个方向,下一个点就变成’*‘
begin
map[a[l].x-i,a[l].y]:='*';
inc(i);
end
else
if hash[a[l].x-i,a[l].y] then
begin
hash[a[l].x-i,a[l].y]:=false;
inc(r);
a[r].x:=a[l].x-i;
a[r].y:=a[l].y;
a[r].d:=a[l].d+1;
inc(i);
end
else
inc(i);
end;
end;
2://南
begin
i:=1;
while map[a[l].x+i,a[l].y]<>'X' do
begin
if a[l].d=n then
begin
map[a[l].x+i,a[l].y]:='*';
inc(i);
end
else
if hash[a[l].x+i,a[l].y] then
begin
hash[a[l].x+i,a[l].y]:=false;
inc(r);
a[r].x:=a[l].x+i;
a[r].y:=a[l].y;
a[r].d:=a[l].d+1;
inc(i);
end
else
inc(i);
end;
end;
3://西
begin
i:=1;
while map[a[l].x,a[l].y-i]<>'X' do
begin
if a[l].d=n then
begin
map[a[l].x,a[l].y-i]:='*';
inc(i);
end
else
if hash[a[l].x,a[l].y-i] then
begin
hash[a[l].x,a[l].y-i]:=false;
inc(r);
a[r].x:=a[l].x;
a[r].y:=a[l].y-i;
a[r].d:=a[l].d+1;
inc(i);
end
else
inc(i);
end;
end;
4://东
begin
i:=1;
while map[a[l].x,a[l].y+i]<>'X' do
begin
if a[l].d=n then
begin
map[a[l].x,a[l].y+i]:='*';
inc(i);
end
else
if hash[a[l].x,a[l].y+i] then
begin
hash[a[l].x,a[l].y+i]:=false;
inc(r);
a[r].x:=a[l].x;
a[r].y:=a[l].y+i;
a[r].d:=a[l].d+1;
inc(i);
end
else
inc(i);
end;
end;
end;
end;
end;
begin
cen:=0;
readln(r,c);
for i:=0 to r+1 do
for j:=0 to c+1 do
map[i,j]:='X';
for i:=1 to r do
begin
for j:=1 to c do
begin
read(map[i,j]);
if map[i,j]='*' then
begin
a[1].x:=i;
a[1].y:=j;
map[i,j]:='.';//起点变为’.’
a[1].d:=1;//第1方向
end;
end;
readln;
end;
readln(n);
for i:=1 to n do
begin
readln(t);
if t='NORTH' then dir[i]:=1;
if t='SOUTH' then dir[i]:=2;
if t='WEST' then dir[i]:=3;
if t='EAST' then dir[i]:=4;
end;
bfs;
for i:=1 to r do
begin
for j:=1 to c do
write(map[i,j]);
writeln;
end;
end.