题意
给定一个迷宫,迷宫中 A 可以向 8 个方向移动(八联通的 8 个方向),B 可以向 4 个方向移动(四联通的 4 个方向),但一单位时间可以移动两次。不能通过障碍物。问 A 和 B 是否能相遇、最早什么时候相遇。
题解
一开始理解错意思了,以为相遇必须是在某一时刻到达同一个格子。于是开始纠结 B 的“走两步”算一个还是半个时刻。
后来发现想多了,只要 A 和 B 都到达过某个格子就行了。那么直接上双向 BFS 即可。
#include <bits/stdc++.h>
#define INF 2000000000
#define MOD 1000000007
#define MAXN 200005
#define REP(temp, init_val, end_val) for (int temp = init_val; temp <= end_val; ++temp)
#define REPR(temp, init_val, end_val) for (int temp = init_val; temp >= end_val; --temp)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> intpair;
int read(){
int f = 1, x = 0;
char c = getchar();
while (c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();}
while (c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar();
return f * x;
}
inline int lowbit(int x){
return x & (-x);
}
inline int modadd(int x, int y){
return (x + y >= MOD ? x + y - MOD: x + y);
}
inline int sgn(int x){
return (x < 0 ? -1: (x > 0 ? 1: 0));
}
template<typename T>
T gcd(T a, T b){
return (!b) ? a: gcd(b, a % b);
}
const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, 1, -1};
const int ddx[] = {-1, -1, -1, 0, 0, 1, 1, 1}, ddy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
int n, m;
int ax, ay, bx, by;
char o[3], mat[1005][1005];
queue<int> qx1, qx2, qy1, qy2;
bool vis1[1005][1005] = {0}, vis2[1005][1005];
void init(){
n = read(), m = read();
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j){
scanf("%s", o);
mat[i][j] = o[0];
if (o[0] == 'C') ax = i, ay = j;
if (o[0] == 'D') bx = i, by = j;
}
}
}
bool stepa(){
int siz1 = qx1.size();
while (siz1--){
int x = qx1.front(), y = qy1.front();
qx1.pop(), qy1.pop();
for (int i = 0; i < 8; ++i){
int cx = x + ddx[i], cy = y + ddy[i];
if (cx <= 0 || cy <= 0 || cx > n || cy > m)
continue;
if (mat[cx][cy] == '#' || vis1[cx][cy]) continue;
vis1[cx][cy] = true;
if (vis2[cx][cy]) return true;
qx1.push(cx), qy1.push(cy);
}
}
return false;
}
bool stepb(){
int siz2 = qx2.size();
while (siz2--){
int x = qx2.front(), y = qy2.front();
qx2.pop(), qy2.pop();
for (int i = 0; i < 4; ++i){
int cx = x + dx[i], cy = y + dy[i];
if (cx <= 0 || cy <= 0 || cx > n || cy > m)
continue;
if (mat[cx][cy] == '#' || vis2[cx][cy]) continue;
vis2[cx][cy] = true;
if (vis1[cx][cy]) return true;
qx2.push(cx), qy2.push(cy);
}
}
return false;
}
bool step(){
if (stepa()) return true;
if (stepb()) return true;
if (stepb()) return true;
return false;
}
void solve(){
vis1[ax][ay] = true;
vis2[bx][by] = true;
qx1.push(ax), qy1.push(ay);
qx2.push(bx), qy2.push(by);
int ans = 0x3f3f3f3f;
for (int st = 1; ; ++st){
if (qx1.empty() && qx2.empty()){
printf("NO\n");
return ;
}
if (step()){
printf("YES\n%d\n", st);
return ;
}
}
}
int main(){
init();
solve();
return 0;
} 
京公网安备 11010502036488号