题目背景
可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。
Input
输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小N*M(1 <= N,M <=10)。T如上所意。接下去的前N*M表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。
Output
如果骑士们能够在T时刻能找到公主就输出“YES”,否则输出“NO”。
Sample Input
1
5 5 14
S*#*.
.#...
.....
****.
...#.
..*.P
#.*..
***..
...*.
*.#..
Sample Output
YES
题目大意:。。。字数不多的中文题。还是说一下吧,给你一个三维地图。地图大小:2*n*m。S是出发坐标,不过题目直接说了是(0,0,0),不用跑一边地图找。*是墙,不能走。P是要到达的公主位置。#是时空穿梭机,可以从当前层的位置到另一层正对的位置。比如(0,1,1)–>(1,1,1)、(1,2,2)–>(2,2,2)。我不确定#是不是只在第0层,所以直接按照#可能两层都可能有做的。
注意:从一层到另一层的时间不算。如果传送的对面是墙,则传送过去勇士(骑士)会GG。从S—>P,步数(时间)要在输入时间 T 的范围内,不然公主就GG了。
Think: BFS广度优先搜索,这题是三维的地图,不过只有两层,不算难,注意层与层之间的跳转的判断就好。
C++代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef struct node
{
int a; //横坐标
int b; //纵坐标
int c; //第几次层
int step; //步数(时间)
} node;
node p[1010]; //题目n、m都比较小,不用开太大
bool b[2][15][15]; //布尔类型,用于标记地图上的点是否走过
int h[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; //跑四个方向的数组
//之前都是用next数组表示,没毛病
//不知道为啥这个名字就报错了,就改名为数组名h了。。。
char s[2][15][15]; //地图
int n, m, k; //地图的行、列。时间
void BFS(); //广搜
int main()
{
int t;
scanf("%d", &t); //习惯t为输入的组数
while(t--)
{
scanf("%d %d %d", &n, &m, &k); //k为截至时间
int i;
for(i = 0; i < n; i++)
{
scanf("%s", s[0][i]);
}
for(i = 0; i < n; i++)
{
scanf("%s", s[1][i]);
}
BFS(); //广搜
}
return 0;
}
void BFS()
{
memset(b, 0, sizeof(b)); //初始都没走过任何位置
int i;
int head = 1;
int top = 1;
p[head].a = 0;
p[head].b = 0;
p[head].c = 0;
p[head].step = 0;
b[0][0][0] = 1; //标记走过
top++;
int aa, bb, cc;
while(head < top)
{
node t = p[head];
if(t.step >= k) //公主会GG,来不及了
{
printf("NO\n");
return ;
}
head++;
for(i = 0; i < 4; i++)
{
aa = t.a + h[i][0];
bb = t.b + h[i][1];
cc = t.c;
if(aa < 0||aa >= n||bb < 0||bb >= m)
{
continue; //超出边界的位置不能入队
}
if(cc == 0) //当前是0层
{
if(b[0][aa][bb] == 1||s[0][aa][bb] == '*')
{
continue; //如果走过了,或者是墙,则止步
}
b[0][aa][bb] = 1; //标记已经走过这个位置
if(s[0][aa][bb] == '.') //入队
{
p[top].a = aa;
p[top].b = bb;
p[top].c = 0;
p[top].step = t.step + 1;
top++;
}
else if(s[0][aa][bb] == '#') //遇到传送机
{ //下面没判断是否为墙*,因为会GG,不需要处理
if(s[1][aa][bb] == 'P') //对面是公主,欢天喜地
{
printf("YES\n");
return ;
}
else if(s[1][aa][bb] == '.') //入队
{
b[1][aa][bb] = 1; //不可少!!!
p[top].a = aa;
p[top].b = bb;
p[top].c = 1;
p[top].step = t.step + 1;
top++;
}
}
else if(s[0][aa][bb] == 'P') //成功到达公主所在地
{
printf("YES\n");
return ;
}
}
else //当前是第一层,道理同上
{
if(b[1][aa][bb]||s[1][aa][bb] == '*')
{
continue;
}
b[1][aa][bb] = 1;
if(s[1][aa][bb] == '.')
{
p[top].a = aa;
p[top].b = bb;
p[top].c = 1;
p[top].step = t.step + 1;
top++;
}
else if(s[1][aa][bb] == '#')
{
if(s[0][aa][bb] == 'P')
{
printf("YES\n");
return ;
}
else if(s[0][aa][bb] == '.')
{
b[0][aa][bb] = 1; //不可少!!!
p[top].a = aa;
p[top].b = bb;
p[top].c = 0;
p[top].step = t.step + 1;
top++;
}
}
else if(s[1][aa][bb] == 'P')
{
printf("YES\n");
return ;
}
}
}
}
printf("NO\n");
}