星际旅行 | ||||||
| ||||||
Description | ||||||
小z在星际旅行中,他想从当前起始点到达目的地,他可以上下左右的移动,并且每移动一格需要花费一单位时间, 星际中有许多危险的地方不可以走,还有许多的黑洞,你可以不花费任何时间从一个黑洞瞬间到达其它任何一个黑洞, 请你帮助小z计算从当前起始点到目的地最少需要多少单位时间。 | ||||||
Input | ||||||
第一行是一个整数T,代表T组测试数据。 对于每组测试数据,首先是两个整数n,m代表星际地图(1<=n<=100, 1<=m<=100) 接下来是一个n*m的地图。 'O' 代表黑洞。 '#' 代表不可以走的地方。 '.' 代表普通的空间。 'S' 代表起始点,有且只有一个。 'E' 代表目的地,有且只有一个。 | ||||||
Output | ||||||
对于每组测试数据,如果小z可以到达目的地,则输出需要的最少时间,否则输出"impossible"。 | ||||||
Sample Input | ||||||
2 3 4 SO.. .... ..OE 3 3 #S# ### E## | ||||||
Sample Output | ||||||
2 impossible | ||||||
Source | ||||||
2014.11.30新生赛-正式赛 |
一道基础BFS题目,和最基础的BFS题目相差一个传送阵的内容。
思路:输入图的同时,用heidong【】【2】数组保存传送阵的坐标,当在图搜过程中的时候,遇到传送阵的时候,直接传到其他传送阵的地点即可、
AC代码:
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct zuobiao
{
int x,y,output;
}now,nex;
int cont;
char a[105][105];//图、
int vis[105][105];//标记这个坐标是否走过
int heidong[105*105][2];//黑洞坐标统计
int fx[4]={0,0,1,-1};
int fy[4]={-1,1,0,0};
int n,m;
void bfs(int x,int y)
{
memset(vis,0,sizeof(vis));
now.output=0;
now.x=x;
now.y=y;
vis[now.x][now.y]=1;
queue<zuobiao >s;
s.push(now);
while(!s.empty())
{
now=s.front();
if(a[now.x][now.y]=='E')
{
printf("%d\n",now.output);
return ;
}
s.pop();
for(int i=0;i<4;i++)
{
nex.x=now.x+fx[i];
nex.y=now.y+fy[i];
if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]!='#')
{
if(a[nex.x][nex.y]=='O')//遇到传送真的时候
{
vis[nex.x][nex.y]=1;
for(int i=0;i<cont;i++)//走到其他传送阵
{
if(vis[heidong[i][0]][heidong[i][1]]==0)
{
nex.output=now.output+1;
nex.x=heidong[i][0];
nex.y=heidong[i][1];
vis[heidong[i][0]][heidong[i][1]]=1;
s.push(nex);
}
}
}
if(a[nex.x][nex.y]=='.'||a[nex.x][nex.y]=='E')//正常向下走即可
{
vis[nex.x][nex.y]=1;
nex.output=now.output+1;
s.push(nex);
}
}
}
}
printf("impossible\n");
return ;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int x,y;
scanf("%d%d",&n,&m);
cont=0;
for(int i=0;i<n;i++)
{
scanf("%s",a[i]);
for(int j=0;j<m;j++)
{
if(a[i][j]=='S')
{
x=i;
y=j;
}
if(a[i][j]=='O')
{
heidong[cont][0]=i;
heidong[cont][1]=j;
cont++;
}
}
}
bfs(x,y);
}
}