这道题可谓有好多解法,既然讲究效率,我还是选择了bfs。
bfs比较难下手,但理解题目后感觉还是挺简单的。
思路现将地图扩展成四份。

O=>OO
   OO

如果超过边界则到对应边的对应位置。
代码:

const z:array[1..4,1..2]of -1..1=((-1,0),(0,-1),(1,0),(0,1));
var i,j,k:longint;
    m,n,h,t:longint;
    fx,fy:longint;
    a:array[0..3001,0..3001]of 1..3;
    x,y:array[0..9000000]of longint;
    ch:char;
procedure add(x,y,p:longint);//扩张
begin
  a[x,y]:=p;
  a[x,y+n]:=p;
  a[x+m,y]:=p;
  a[x+m,y+n]:=p;
end;
function pdx(x:longint):longint;//判断地图实际坐标
begin
  if x=0 then exit(m*2);
  if x=m*2+1 then exit(1);
  exit(x);
end;
function pdy(y:longint):longint;//判断地图实际坐标
begin
  if y=0 then exit(n*2);
  if y=n*2+1 then exit(1);
  exit(y);
end;
begin
  while not eof do
  begin
    m:=0;
    n:=0;
    readln(m,n);
    if(m=0) and (n=0) then exit;//坑人的回车键
    for i:=1 to m do
    begin
      for j:=1 to n do
      begin
        read(ch);
        if ch=\'S\' then 
        begin
        fx:=i;
        fy:=j;
        add(i,j,1);
        end;
        if ch=\'.\' then add(i,j,2);
        if ch=\'#\' then add(i,j,3);
      end;
      readln;
    end;
    for i:=1 to m*2 do//打上边界
    begin
      a[i,0]:=3;
      a[i,n*2+1]:=3;
    end;
    for i:=1 to n*2 do//打上边界
    begin
      a[0,i]:=3;
      a[m*2+1,i]:=3;
    end;
    h:=1;
    t:=1;
    k:=0;
    a[fx,fy]:=3;
    x[1]:=fx;
    y[1]:=fy;
    repeat//bfs
      for i:=1 to 4 do
      if a[pdx(x[t]+z[i,1]),pdy(y[t]+z[i,2])]<>3 then
      begin
        inc(h);
        x[h]:=pdx(x[t]+z[i,1]);
        y[h]:=pdy(y[t]+z[i,2]);
        if a[x[h],y[h]]=1 then//可以回到起点
        begin
          k:=1;
          break;
        end;
        a[x[h],y[h]]:=3;
      end;
      inc(t);
      if k=1 then break;//找到解了
    until t>h;
    if k=1 then writeln(\'Yes\') else writeln(\'No\');//输出答案
  end;
end.

其实也没什么要讲的,bfs都差不多。

收藏 打印