题目描述
500 年前,Jesse 是我国最卓越的剑客。他英俊潇洒,而且机智过人 ^_^。
突然有一天,Jesse 心爱的公主被魔王困在了一个巨大的迷宫中。Jesse 听说这个消息已经是两天以后了,他知道公主在迷宫中还能坚持 TTT 天,他急忙赶到迷宫,开始到处寻找公主的下落。 时间一点一点的过去,Jesse 还是无法找到公主。最后当他找到公主的时候,美丽的公主已经死了。从此 Jesse 郁郁寡欢,茶饭不思,一年后追随公主而去了。T_T
500 年后的今天,Jesse 托梦给你,希望你帮他判断一下当年他是否有机会在给定的时间内找到公主。
他会为你提供迷宫的地图以及所剩的时间 TTT。请你判断他是否能救出心爱的公主。
输入
题目包括多组测试数据。
每组测试数据以三个整数 N,M,TN, M, TN,M,T(0<n,m≤20;t>00 \lt n, m \le 20; t \gt 00<n,m≤20;t>0)开头,分别代表迷宫的长和高,以及公主能坚持的天数。
紧接着有 MMM 行,NNN 列字符,由 .
,*
,P
,S
组成。其中 .
代表能够行走的空地。*
代表墙壁,Jesse 不能从此通过。P
是公主所在的位置。 S
是 Jesse 的起始位置。
每个时间段里 Jesse 只能选择“上、下、左、右”任意一方向走一步。输入以 0 0 0
结束。
输出
如果能在规定时间内救出公主输出 YES
,否则输出 NO
。
输入输出样例
样例输入 #1
4 4 10
....
....
....
S**P
0 0 0
样例输出 #1
YES
c++代码(bfs无函数调用):
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue> //队列
#define F(a,begin,end) for(register int a=begin;a<end;a++) //宏
using namespace std;
const int MAXN = 25;
int m, n, T; //监狱长、宽、时间
char arr[MAXN][MAXN]; //监狱
int visited[MAXN][MAXN] = { 0 };
int step[4][2] = { 1,0,-1,0,0,1,0,-1 };//骑士行走的方向
struct steps {
int x, y, t;
steps(int xx, int yy, int tt) :x(xx), y(yy), t(tt) {}
};
queue<steps >q;
int main() {
while (cin >> n >> m >> T) { //按题目要求,先输入的是列再是行!!!
bool flag = 0; //判断是否可以找到公主
memset(visited, 0, sizeof(visited));//初始化
memset(arr, 0, sizeof(arr));//初始化
while (!q.empty()) q.pop();//将队列清空
int x, y;
if (m + n + T == 0) break; //样例输入终止条件
F(i, 0, m) F(j, 0, n) {
cin >> arr[i][j];
if (arr[i][j] == 'S') { //记录初始位置
x = i;
y = j;
}
if (arr[i][j] == '*') visited[i][j] = 1; //墙->不能走
}
q.push(steps(x, y, 0));
visited[x][y] = 1;
while (!q.empty()) {
steps s = q.front();
q.pop();
if (arr[s.x][s.y] == 'P') {
flag = 1; //可以找到皇后
if (s.t <= T) cout << "YES" << endl;
else cout << "NO" << endl;
break;
}
else {
F(i, 0, 4) {
int a = s.x + step[i][0];
int b = s.y + step[i][1];
if (s.t > T) continue; //剪枝
if (a >= m || b >= n || a < 0 || b < 0) continue;
if (arr[a][b]=='*'||visited[a][b]) continue;
visited[a][b] = 1;
q.push(steps(a, b, s.t + 1));
}
}
}
if(!flag) cout<<"NO"<<endl; //无法找到
}
return 0;
}
c++代码(bfs函数调用)
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#define F(a,begin,end) for(register int a=begin;a<end;a++)
using namespace std;
const int MAXN = 25;
int m, n, T;
char arr[MAXN][MAXN];
int visited[MAXN][MAXN],step[4][2] = { 1,0,-1,0,0,1,0,-1 };
struct steps {
int x, y, t;
steps(int xx, int yy, int tt) :x(xx), y(yy), t(tt) {}
};
int bfs(int x, int y) {
queue<steps >q;
q.push(steps(x, y, 0));
visited[x][y] = 1;
while (!q.empty()) {
steps s = q.front();
q.pop();
if (arr[s.x][s.y] == 'P') return s.t;
F(i, 0, 4) {
int a = s.x + step[i][0];
int b = s.y + step[i][1];
if (a < m && b < n &&a >= 0 && b >= 0 && !visited[a][b]) {
visited[a][b] = 1;
q.push(steps(a, b, s.t + 1));
}
}
}
return 100000000;
}
int main() {
while (cin >> n >> m >> T) {
int x, y;
if (m+n+T==0) break;
memset(visited, 0, sizeof(visited));
memset(arr, 0, sizeof(arr));
F(i, 0, m) F(j, 0, n) {
cin >> arr[i][j];
if (arr[i][j] == 'S') x=i,y=j;
else if (arr[i][j] == '*') visited[i][j] = 1;
}
if (bfs(x,y) > T) cout << "NO" << endl;
else cout << "YES" << endl;
}
return 0;
}