来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
小A与小B这次两个人都被困在了迷宫里面的两个不同的位置,而他们希望能够迅速找到对方,然后再考虑如何逃离迷宫的事情。小A每次可以移动一个位置,而小B每次可以移动两次位置,小A移动的方向是上下左右左上左下右上右下8个方向,小B移动的方向是上下左右4个方向,请问他们最早什么时候能够找到对方,如果他们最终无法相遇,那么就输出”NO"。
输入描述:
第一行两个整数N,M分别表示迷宫的行和列。
接下来一个N * M的矩阵,其中 "C" 表示小A的位置, "D" 表示小B的的位置,"#" 表示不可通过的障碍, "." 则是可以正常通过的位置。字符用空格隔开,第>一行两个整数N,M分别表示迷宫的行和列。
输出描述:
如果可以相遇,第一行输出一个YES,第二行一个整数输出最短的相遇时间。
否则就输出一个NO表示不能相遇。
输入
4 5
. . . . .
. # # # .
. . . # D
. . C # .
输出
YES
3
备注:
1 ≤ n, m ≤ 1000
解题思路
很明显的迷宫问题,用BFS搜索
开两个队列,两个vis数组记录两个人的路程,如果两个vis数组的同一个位置都被标记了,就说明相遇。如果两个队列都空了都没有相遇说明不可能。
另外说这道题的坑还是蛮多的
· 小B每次可以走两步的,所以简单粗暴bfs两次
· 输入时带空格,由于我一直用cin所以没啥影响
· 判定边界的时候把#这个点漏了可把孩子吓到了
· 必须两个队列都空才能判定是NO,&&和||别弄反了(哭
代码
#include <bits/stdc++.h>
using namespace std;
int n, m;
char Map[1007][1007];
queue<pair<int, int> > q[2];
bool vis[2][1007][1007];
int dx[10] = {0, 1, 0, -1, 0, 1, 1, -1, -1};
int dy[10] = {0, 0, 1, 0, -1, 1, -1, 1, -1};
bool bfs(int x){
int len = q[x].size();
while(len--){
pair<int, int> p = q[x].front();
q[x].pop();
int l = 0;
if(x == 0) l = 8;
else l = 4;
for(int i = 1; i <= l; i++){
int xx = p.first + dx[i];
int yy = p.second + dy[i];
if(xx > 0 && xx <= n && yy > 0 && yy <= m && Map[xx][yy] != '#' && vis[x][xx][yy] == 0){
if(vis[x ^ 1][xx][yy] == 1) return 1;
vis[x][xx][yy] = 1;
q[x].push(make_pair(xx, yy));
}
}
}
return 0;
}
int f(){
int ans = 0;
while(q[0].size() != 0 || q[1].size() != 0){
ans++;
if(bfs(0)) return ans;
if(bfs(1)) return ans;
if(bfs(1)) return ans;
}
return -1;
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> Map[i][j];
if(Map[i][j] == 'C') {
q[0].push(make_pair(i, j));
vis[0][i][j] = 1;
}
if(Map[i][j] == 'D') {
q[1].push(make_pair(i, j));
vis[1][i][j] = 1;
}
}
}
int ans = f();
if(ans == -1)
cout << "NO";
else
cout << "YES" << endl << ans;
return 0;
}
午安
End.

京公网安备 11010502036488号