codevs1026

题目地址: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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值