题目大意:
在一种”麻将”游戏中,游戏是在一个有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.