解救小Q
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=121832#problem/COR
http://acm.uestc.edu.cn/#/problem/show/149
小Q被邪恶的大魔王困在了迷宫里,love8909决定去解救她。
迷宫里面有一些陷阱,一旦走到陷阱里,就会被困身亡:(,迷宫
里还有一些古老的传送阵,一旦走到传送阵上,会强制被传送到
传送阵的另一头。
现在请你帮助love8909算一算,他至少需要走多少步才能解
救到小Q?
Input
第一行为一个整数$T$,表示测试数据组数。
每组测试数据第一行为两个整数$N$,$M$,($1\leq N, M\leq 50$)表示
迷宫的长和宽。
接下来有$N$行,每行$M$个字符,是迷宫的具体描述。
.
表示安全的位置#
表示陷阱,Q
表示小Q的位置L
表示love8909所在位置,
数据保证love8909只有一个,数据也保证小Q只有一个。
小写字母a
-z
表示分别表示不同的传送阵,数据保证传送阵
两两配对。
Output
每组数据输出一行,解救小Q所需的最少步数,如果无论如何都
无法救小Q,输出-1
。
Sample Input
2 5 5 ....L .###. b#b#a ##.## ...Qa 5 5 ....L .###. .#.#. ##.## ...Q.
Sample Output
3
-1
例子
10
5 5
....L
.###.
b#b#a
##.##
...Qa
5 5
....L
.###.
.#.#.
##.##
...Q.
4 4
Qa..
b#..
.a#.
.b#L
4 4
Qa..
##..
.a#.
.##L
5 4
....
.#a.
#Q#.
#.#.
.aL.
5 5
..Qa.
.....
..La.
.....
.....
5 5
..Qa.
.....
.....
..La.
.....
3 -1 7 8 5 2 2
两个传送门入口走过,出口没走过,传送门强制传送
#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;
struct no
{
int x,y;
int step;
};
int dir[4][2] = {0,1,0,-1,1,0,-1,0};
char m[70][70];
int vis[70][70];
int lx,ly;
int qx,qy;
int tr[30][5];
int istr[30];
int xmax,ymax;
int check(int xx,int yy)
{
if(vis[xx][yy] == 1||m[xx][yy] == '#'||xx<0||yy<0||xx>=xmax||yy>=ymax)
return 0;
return 1;
}
int bfs()
{
queue<no> q;
if(!q.empty())
q.pop();
no a,next;
a.x = lx;
a.y = ly;
vis[lx][ly] = 1;
a.step = 0;
m[lx][ly] = '#';
q.push(a);
while(!q.empty())
{
a = q.front();
q.pop();
for(int i = 0;i < 4;i++)
{
next = a;
next.x = a.x+dir[i][0];
next.y = a.y+dir[i][1];
if(check(next.x,next.y))
{
next.step++;
if(m[next.x][next.y]>='a'&&m[next.x][next.y]<='z')
{
int aa = (int)m[next.x][next.y] - 'a';
if(next.x == tr[aa][0]&&next.y == tr[aa][1])
{
vis[next.x][next.y] = 1;
next.x = tr[aa][2];
next.y = tr[aa][3];
}
else
{
vis[next.x][next.y] = 1;
next.x = tr[aa][0];
next.y = tr[aa][1];
}
if(m[next.x][next.y] == 'Q')
{
return next.step;
}
q.push(next);
}
else
{
vis[next.x][next.y]= 1;
if(m[next.x][next.y] == 'Q')
{
return next.step;
}
q.push(next);
}
}
}
}
return -1;
}
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--)
{
memset(m,0,sizeof(m));
memset(istr,0,sizeof(istr));
memset(vis,0,sizeof(vis));
memset(tr,0,sizeof(tr));
scanf("%d%d",&xmax,&ymax);
for(int i = 0;i < xmax;i++)
{
scanf("%s",m[i]);
for(int j = 0;j < ymax;j++)
{
if(m[i][j] == 'L')
{
lx = i;
ly = j;
}
if(m[i][j] == 'Q')
{
qx = i;
qy = j;
}
if(m[i][j]>='a'&&m[i][j]<='z')
{
if(istr[(int)m[i][j]-'a' ]== 0)
{
tr[(int)m[i][j]-'a'][0] = i;
tr[(int)m[i][j]-'a'][1] = j;
istr[(int)m[i][j]-'a' ] = 1;
}
else
{
tr[(int)m[i][j]-'a'][2] = i;
tr[(int)m[i][j]-'a'][3] = j;
}
}
}
}
printf("%d\n",bfs());
}
return 0;
}