麻将游戏
Time Limit:10000MS Memory Limit:65536K
Total Submit:237 Accepted:86
Case Time Limit:1000MS
Description
在一种"麻将"游戏中,游戏是在一个有
W
*
H
W*H
W*H格子的矩形平板上进行的。每个格子可以放置一个麻将牌,也可以不放(如图所示)。玩家的目标是将平板上的所有可通过一条路径相连的两张相同的麻将牌,从平板上移去。最后如果能将所有牌移出平板,则算过关。
这个游戏中的一个关键问题是:两张牌之间是否可以被一条路径所连接,该路径满足以下两个特性:
1. 它由若干条线段组成,每条线段要么是水平方向,要么是垂直方向。
2. 这条路径不能横穿任何一个麻将牌 (但允许路径暂时离开平板)。
这是一个例子:
在
(
1
,
3
)
(1,3)
(1,3)的牌和在
(
4
,
4
)
(4, 4)
(4,4)的牌可以被连接。
(
2
,
3
)
(2, 3)
(2,3)和
(
3
,
4
)
(3, 4)
(3,4)不能被连接。
你的任务是编一个程序,检测两张牌是否能被一条符合以上规定的路径所连接。
Input
输入文件的第一行有两个整数
w
,
h
(
1
<
=
w
,
h
<
=
75
)
w,h (1<=w,h<=75)
w,h(1<=w,h<=75),表示平板的宽和高。接下来
h
h
h行描述平板信息,每行包含
w
w
w个字符,如果某格子有一张牌,则这个格子上有个
′
X
′
'X'
′X′,否则是一个空格。平板上最左上角格子的坐标为
(
1
,
1
)
(1,1)
(1,1),最右下角格子的坐标为
(
w
,
h
)
(w,h)
(w,h)。接下来的若干行,每行有四个数
x
1
,
y
1
,
x
2
,
y
2
x1, y1, x2, y2
x1,y1,x2,y2,且满足
1
<
=
x
1
,
x
2
<
=
w
,
1
<
=
y
1
,
y
2
<
=
h
1<=x1,x2<=w,1<=y1,y2<=h
1<=x1,x2<=w,1<=y1,y2<=h,表示两张牌的坐标(这两张牌的坐标总是不同的)。如果出现连续四个
0
0
0,则表示输入结束。
Output
输出文件中,对于每一对牌输出占一行,为连接这一对牌的路径最少包含的线段数。如果不存在路径则输出
0
0
0。
Sample Input
5 4
XXXXX
X (三个空格) X
XXX (一个空格)X
(一个空格) XXX (一个空格)
2 3 5 3
1 3 4 4
2 3 3 4
0 0 0 0
Sample Output
4
3
0
解题思路
很明显,这又又…又是一道BFS,(毕竟作者还在学)让我们求对牌的路径最少包含的线段数。。。
其实就是 最小转弯问题 答案加一。。
小小的变化:
1.
1.
1.字符输入,
‘
X
’
‘X’
‘X’ 为
1
1
1,
‘
’
‘ ’
‘’ 为
0
0
0。
2.
2.
2.要注意“允许路径暂时离开平板“”。
3.
3.
3.每个数据输出后要给一些标记的数组清零。
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int dx[5]={0,0,1,0,-1};
const int dy[5]={0,1,0,-1,0};
int n,m,a,b,c,d,bsy[200][200];
int st[300000][4],fa[200][200];
int h=0,t=1,ans;
int s;
bool check(int x,int y)
{
if(x>=0&&x<=n+1&&y>=0&&y<=m+1&&!bsy[x][y])如果碰到墙就结束拓展,但可超出平板一圈
return 1;
else
return 0;
}
void bfs(){
h=0; t=1;
st[1][1]=a;
st[1][2]=b;
st[1][3]=0;
bsy[c][d]=0; //一定记得要给终点解封
fa[a][b]=1;
do{
h++;
for(int k=1;k<=4;k++)
{
int xx,yy;
xx=st[h][1]; yy=st[h][2];
while(check(xx+dx[k],yy+dy[k]))
{
if(!fa[xx+dx[k]][yy+dy[k]])
{ //如果已经走过的路线就不入队
t++;
st[t][1]=xx+dx[k];//储存位置
st[t][2]=yy+dy[k];//储存位置
st[t][3]=st[h][3]+1;//储存转弯数
fa[xx+dx[k]][yy+dy[k]]=1;//标记已经走过该地
if(st[t][1]==c&&st[t][2]==d)//结束判断
{
s=st[t][3];
return;
}
}
xx+=dx[k]; yy+=dy[k];
}
}
}while(h<t);
}
int main(){
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++)//字符读入
{
char c=getchar();
for(int j=1;j<=m;j++){
char c=getchar();
if(c=='X')
bsy[i][j]=1;
else
bsy[i][j]=0;
}
}
scanf("%d%d%d%d",&b,&a,&d,&c);
while(a)
{
s=0;
bfs();
if(fa[c][d])cout<<s<<endl;
else
cout<<0<<endl;
memset(fa, 0, sizeof(fa));
bsy[c][d]=1;//重新给终点封锁
scanf("%d%d%d%d",&b,&a,&d,&c);
}
}