1.题目
问题描述
勇士们不小心进入了敌人的地雷阵(用n行n列的矩阵表示,'*'表示某个位置埋有地雷,'-'表示某个位置是安全的),他们各自需要在规定的步数(一步代表走到和当前位置相邻的位置)内绕开地雷到达出口(第一行第一格,即坐标为(0,0)的位置)才能完成任务,告诉你每个勇士的位置(x,y)和规定的步数s,请你判断每个勇士能否顺利完成任务(1代表“能”,-1代表“不能”)。
输入格式
输入数据的第一行为一个整数n;第二行至第n+1行是n行n列地雷阵的矩阵表示(见输入样例);第n+2行至最后一行每行是一个勇士的位置x、y和到达出口规定的最大步数s,三个整数间用空格隔开。
输出格式
按顺序输出对每个勇士是否能顺利完成任务的判断(1代表“能”,-1代表“不能”),对每个勇士的判断占一行。
样例输入
5
-----
--*--
-**--
-**--
*-*--
0 1 1
0 4 3
1 1 3
1 4 2
2 0 3
3 0 4
3 3 2
4 1 3
样例输出
1
-1
1
-1
1
1
-1
-1
数据规模和约定
1≤n≤500,0≤x≤n-1,0≤y≤n-1,1≤s≤500
2.思路
不难看出这题与求迷宫问题的最短路径相似,不过如果按输入一个一个“勇士”进行搜索必然会超时。这时不如换个角度思考,既然都要走到(0,0),不如从(0,0)开始搜索整个迷宫并记录到每一处的最短路径长度,再按照查表的方式输出结果。
3.代码
#include <bits/stdc++.h>
using namespace std;
int x_way[4] = { 0, 0, 1, -1 };
int y_way[4] = { 1, -1, 0, 0 };
struct point {
int x;
int y;
int step;
point(int x, int y, int step) {
this->x = x;
this->y = y;
this->step = step;
}
};
//广度搜索
void BFS(vector<vector<int> >&step, vector<vector<char> >mp, int n) {
queue<point>myqueue;
point p(0, 0, 0);
mp[0][0] = '*';
myqueue.push(p);
while (!myqueue.empty()) {
point tmp = myqueue.front();
myqueue.pop();
for (int i = 0; i < 4; ++i) {
point p(tmp.x + x_way[i], tmp.y + y_way[i], tmp.step + 1);
if (p.x >= 0 && p.x < n && p.y >= 0 && p.y < n && mp[p.x][p.y] != '*') {
myqueue.push(p);
step[p.x][p.y] = p.step;
mp[p.x][p.y] = '*';
}
}
}
}
int main() {
int n;
cin >> n;
vector<vector<char> >mp(n, vector<char>(n));
vector<vector<int> >step(n, vector<int>(n, -1));
step[0][0] = 0;
for (int i = 0; i < n; ++i) {
for (int k = 0; k < n; ++k) {
cin >> mp[i][k];
}
}
BFS(step, mp, n);
int x, y, max_step;
while (cin >> x >> y >> max_step) {
if (step[x][y] == -1 || step[x][y] > max_step) {
cout << -1 << endl;
}
else {
cout << 1 << endl;
}
}
return 0;
}