SSL P1786 麻将游戏

题目大意:
在一种”麻将”游戏中,游戏是在一个有W*H格子的矩形平板上进行的。每个格子可以放置一个麻将牌,也可以不放(如图所示)。玩家的目标是将平板上的所有可通过一条路径相连的两张相同的麻将牌,从平板上移去。
这个游戏中的一个关键问题是:两张牌之间是否可以被一条路径所连接,该路径满足以下两个特性:
①它由若干条线段组成,每条线段要么是水平方向,要么是垂直方向。
②这条路径不能横穿任何一个麻将牌 (但允许路径暂时离开平板)。
例:
这里写图片描述
让你检测两张牌是否能被一条符合以上规定的路径所连接,如果可以则输出连接这一对牌的路径最少包含的线段数,如果不存在路径则输出0。

1<=w,h<=75

题解:
广搜:
这题就是个最小转弯问题,只不过有多个查询,
最小转弯就是你的答案只记录从起点到这个点的最少转弯次数是多少,在bfs的过程中去跑并不断更新就可以了。
然后我们要注意!
这里写图片描述
咳咳,上面的Y为空格。
然后对于这题除了可以跳出方格外就没什么不同的,就是最小转弯,对于可以跳出去,你直接在外围加一圈空格Y。

const
    dx:array [1..4] of integer=(-1,0,1,0);
    dy:array [1..4] of integer=(0,1,0,-1);

var
    a,c:Array [-1..77,-1..77] of longint;
    f:Array [0..100001] of longint;
    q:Array [0..100001,1..2] of longint;
    i,j,px,py,qx,qy,n,m:longint;
    flag:boolean;
    d:char;

function check(x,y:longint):boolean;
   begin
     if (x<0) or (x>n) or (y<0) or (y>m) or (a[x,y]=1)
        then exit(false);
    exit(true)
   end;

procedure bfs;
var
    head,tail,k,i,j,x,y:longint;
begin
     fillchar(c,sizeof(c),0);
     head:=0; tail:=1;
     q[1,1]:=px;
     q[1,2]:=py;
     f[1]:=0;
     c[px,py]:=1;
     while head<tail do
     begin
         inc(head);
         for k:=1 to 4 do
           begin
               x:=q[head,1]+dx[k];
               y:=q[head,2]+dy[k];
               while check(x,y) do
               begin
                  if c[x,y]<>1 then
                     begin
                        inc(tail);
                        f[tail]:=f[head]+1;
                        q[tail,1]:=x;
                        q[tail,2]:=y;
                        if (q[tail,1]=qx) and (q[tail,2]=qy)
                        then begin
                               writeln(f[tail]);
                               flag:=false;
                               exit;
                             end;
                        c[x,y]:=1;
                     end;
                  x:=x+dx[k];
                  y:=y+dy[k];
               end;
           end;
     end;
end;


begin
   readln(m,n);
   for i:=1 to n do
     begin
         for j:=1 to m do
           begin
                read(d);
                if d='X' then a[i,j]:=1;
           end;
         readln;
     end;
  n:=n+1; m:=m+1;
  readln(py,px,qy,qx);
  while (px<>0) or (py<>0) or (qx<>0) or (qy<>0) do
  begin
      if (a[px,py]<>1) or (a[qx,qy]<>1)
         then writeln(0)
         else begin
                    a[px,py]:=0; a[qx,qy]:=0;
                    flag:=true; bfs;
                    a[px,py]:=1; a[qx,qy]:=1;
                    if flag then writeln(0);
              end;
      readln(py,px,qy,qx);
  end;
end.
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值