解救小Q

解救小Q

时间限制(普通/Java):3000MS/10000MS          运行内存限制:65536KByte

描述

 

小Q被邪恶的大魔王困在了迷宫里,love8909决定去解救她。迷宫里面有一些陷阱,一旦走到陷阱里,就会被困身亡:(,迷宫里还有一些古老的传送阵,一旦走到传送阵上,会强制被传送到传送阵的另一头。

现在请你帮助love8909算一算,他至少需要走多少步才能解救到小Q? (上下左右四个方向走,传送门可以多次使用)

 

输入

第一行为一个整数T,表示测试数据组数。每组测试数据第一行为两个整数N,M,(1 <= N, M <= 50)表示迷宫的长和宽。接下来有N行,每行M个字符,是迷宫的具体描述。 '.'表示安全的位置,'#'表示陷阱, 'Q'表示小Q的位置,'L'表示love8909所在位置, 数据保证love8909只有一个,数据也保证小Q只有一个。小写字母'a'-'z'表示分别表示不同的传送阵,数据保证传送阵两两配对。

输出

每组数据输出一行,解救小Q所需的最少步数,如果无论如何都无法救小Q,输出-1。

 

样例输入

2

5 5

....L

.###.

b#b#a

##.##

...Qa

5 5

....L

.###.

.#.#.

##.##

...Q.

 

样例输出

3

-1

 

题解:广搜,不过从第一个传送门到第二个传送门时,第一个需要标记已走过,而第二个不能被标记。

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

int dir[4][2]={0,1,-1,0,0,-1,1,0}; //四个方向
int startx,starty,n,m; bool flag[60][60]; //标记传送门是否已走过
char str[60][60]; //传送门的坐标 struct protal { int x1,y1,x2,y2; }pro[35]; struct cur { int x,y; int step; }; bool BFS() { cur p; queue<cur> Q; p.x = startx; p.y = starty; p.step = 0; Q.push(p); memset(flag,0,sizeof(flag)); flag[p.x][p.y] = 1; while(!Q.empty()) { cur q = Q.front(); //cout<<q.x <<" "<<q.y<<" "<<q.step<<endl; Q.pop(); if(str[q.x][q.y]=='Q') { printf("%d\n",q.step); return false; } for(int i=0;i<4;i++) { int dx = q.x + dir[i][0]; int dy = q.y + dir[i][1]; if(dx>=0&&dx<n&&dy>=0&&dy<m && str[dx][dy]!='#' && !flag[dx][dy]) { if(islower(str[dx][dy])) { if(pro[str[dx][dy]-'a'].x1 == dx && pro[str[dx][dy]-'a'].y1 == dy) { p.x = pro[str[dx][dy]-'a'].x2; p.y = pro[str[dx][dy]-'a'].y2; } else { p.x = pro[str[dx][dy]-'a'].x1; p.y = pro[str[dx][dy]-'a'].y1; } p.step = q.step + 1; Q.push(p); } else { p.x = dx; p.y = dy; p.step = q.step + 1; Q.push(p); } flag[dx][dy] = 1; } } } return true; } int main() { int T,i,j,k; scanf("%d",&T); while(T--) { for(i=0;i<26;i++) pro[i].x1 = -1; scanf("%d%d",&n,&m); for(i=0;i<n;i++) for(j=0;j<m;j++) { cin>>str[i][j]; if(str[i][j]=='L')//记录开始位置 { startx = i; starty = j; }else if(islower(str[i][j]))//str[i][j]是小写字母 { if(pro[str[i][j]-'a'].x1==-1) { pro[str[i][j]-'a'].x1 = i; pro[str[i][j]-'a'].y1 = j; }else { pro[str[i][j]-'a'].x2 = i; pro[str[i][j]-'a'].y2 = j; } } } if(BFS()) puts("-1"); } return 0; }


 


 

 

转载于:https://www.cnblogs.com/lavender913/p/3327125.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值