您的位置:首页 > 其它

BOJ 1433 Tom 的潜望镜 优先队列+BFS

2011-11-03 08:36 183 查看
Description

Tom和Jerry这对活宝最近又开始闹腾了,为了和Jerry斗智斗勇,Tom特地到北邮物理系学习光学的知识,通过自己的不懈努力,他终于学会了潜望镜的制作。学业期满后,他决定和Jerry来一次比赛,在比赛之前,我们先来看看潜望镜的相关知识:



上图就是一个简单的潜望镜,光线经过镜面反射后转过90度射出。于是如图的潜望镜可以使上下两个孔互相看见。

Tom和Jerry比赛在一个n*m的迷宫内进行,Tom在迷宫的A位置,Jerry在迷宫的B位置,Tom希望利用潜望镜原理安装一些镜子找到Jerry。如下图所示:

. . . . . . .       . . . . . . .
. . . . . . J       . . . . . /-J
. . . . . . *       . . . . . | *
* * * * * . *       * * * * * | *
. . . . * . .       . . . . * | .
. . . . * . .       . . . . * | .
. T . . * . .       . T . . * | .
. . . . . . .       . \-------/ .
图1                  图2

迷宫中 ‘*’代表墙,’.’代表可以到达。在右边地图中,Tom在安装了3个镜子(/或\代表镜子)后就可以找到Jerry。现在Tom告诉你地图的信息,他希望你帮助他用最少的镜子找到Jerry。

Input

多组数据测试,输入的第一行是一个正整数t(1 <= t <= 20),表示有t组测试数据。

对于每组测试数据,第一行是两个正整数m,n(1 <= n, m <= 100),表示地图由m列n行组成。接下来有n行,第i行代表着地图的第i行。地图有’.’ , ’*’ , ‘T’ , ‘J’组成。’T’代表Tom的位置,’J’代表Jerry的位置。

Output

对于每组数据,输出Tom最少需要多少个镜子才能找到Jerry。数据保证Tom一定可以找到Jerry。

Sample Input

1
7 8
.......
......J
......*
*****.*
....*..
....*..
.T..*..
.......


Sample Output

3

和普通的走迷宫相同的地方是:对每个点,有四个方向可以走,所以BFS去找。

不同的地方:是找转弯最少的路径,所有BFS的时候用优先队列,每个点结构有一个转弯次数作为优先队列的优先值。

注意对每个点,有四个方向,但是不只是push四个点进去,是四个方向可以到达的所有的点都一起push进队列。

代码里把vis矩阵故意设置成int型是为了调试的时候方便检查每个点的level值。

可以在输出结果里面输出看看vis的值就很容易明白。

#include<iostream>
#include<queue>
using namespace std;
const int N=105;
int row,col;
char mat

;
int sx,sy;
int ex,ey;
int movx[4]={0,0,-1,1};
int movy[4]={-1,1,0,0};
int vis

;
bool inmat(int x,int y)
{
if(x>=0&&y>=0&&x<col&&y<row&&mat[y][x]!='*'&&!vis[y][x])
return true;
return false;
}

struct Point
{
int x,y;
int level;
Point(int a,int b,int l)
{
x=a;
y=b;
level=l;
}
friend bool operator < (const  Point &a,const  Point &b)
{
return a.level>b.level;
}
};

void bfs()
{
priority_queue<Point> que;
que.push(Point(sx,sy,1));
vis[sy][sx]=1;
while(!que.empty())
{
Point now=que.top();
if(now.x==ex&&now.y==ey)
{
printf("%d\n",now.level-2);
/*for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
printf("%d ",vis[i][j]);
}
printf("\n");
}
return ;*///这里把vis矩阵故意设置成int型是为了调试的时候方便检查每个点的level值。
}
que.pop();
for(int i=0;i<4;i++)
{
int nx=now.x+movx[i];
int ny=now.y+movy[i];
while(inmat(nx,ny))
{
que.push(Point(nx,ny,now.level+1));
vis[ny][nx]=now.level+1;
nx+=movx[i];
ny+=movy[i];
}
}
}

}
int main()
{

int cases;
scanf("%d",&cases);
while(cases--)
{
memset(vis,0,sizeof(vis));
scanf("%d%d",&col,&row);
for(int i=0;i<row;i++)
{
scanf("%s",mat[i]);
for(int j=0;j<col;j++)
{
if(mat[i][j]=='T')
{
sx=j;
sy=i;
}
else if(mat[i][j]=='J')
{
ex=j;
ey=i;
}
}
}
bfs();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: