示例1
输入
4 5 . . . . . . # # # . . . . # D . . C # .
输出
YES 3
备注:
1<=n,m<=1000
能够想到是让两人同时bfs搜索,但是实际写的时候 在很多地方出了错
1.B的走要分两次来走,不能一次直接走到最远的可达处,就是一次走两步,因为这样可能会跳过‘#’,从而出错;
2.每走一步都要把上次的“起点”全部走完,得到的新起点用于下一步的行动,所以这两种点“这一次的起点”,“下一次的起点”要分开存,不能混到一起,这里我是开了一个新的暂存对列,让其分别存每个人这一步的起点,然后让下一次的起点存放到q1和q2中,再下一步开始时,再先后把q1,q2中的点存放到q3中,因为A和B是分开走的,每个人走完后q3都会被清空,所以用一个q3分别存储就够了
下面是代码:
#include<bits/stdc++.h>
#include<queue>
#define endl '\n'
using namespace std;
typedef pair<int,int> PII;
const int N = 1001;
int n , m;
char g[N][N];
bool st[N][N][2];//如果1带你2同时为true,说明两人互相找到
int sx1,sy1,sx2,sy2;
int dx1[]={0,0,1,-1,1,1,-1,-1},dy1[]={1,-1,0,0,1,-1,-1,1};//A
int dx2[]={0,0,1,-1,0},dy2[]={1,-1,0,0,0};//B
int bfs(){//两人同时bfs
int time=0;
queue<PII> q1;//存放终点
queue<PII> q2;//存放终点
queue<PII> q3;//暂存队列,存放起点
q1.push({sx1,sy1});
q2.push({sx2,sy2});
st[sx1][sy1][0] = st[sx2][sy2][1] = true;
if(sx1==sx2&&sy1==sy2) return time;//特判,起点相同
while(q1.size()||q2.size()){
time++;
while(q1.size()){
q3.push(q1.front());//存放上一次的要走点
q1.pop();
}
while(q3.size()){
auto t1 =q3.front();
int x1 = t1.first , y1 = t1.second;
q3.pop();
st[x1][y1][0] = true;
for(int i=0;i<8;i++){//让A先走
int nx1 = x1 +dx1[i],ny1 = y1 + dy1[i];
if(nx1 >= 1 && ny1 >= 1 && nx1 <= n && ny1 <= m && !st[nx1][ny1][0] && g[nx1][ny1] != '#'){
st[nx1][ny1][0] = true ;
if(st[nx1][ny1][1]) return time;
q1.push({nx1,ny1});//存放下一次要走的
// cout<<nx1<<" "<<ny1<<endl;
}
}
}
while(q2.size()){
q3.push(q2.front());//存放上一次的要走点
q2.pop();
}
while(q3.size()){
auto t2 =q3.front();
int x2 = t2.first , y2 = t2.second;
q3.pop();
for(int i=0;i<4;i++){//再让B走第一步
int nx2 = x2 +dx2[i],ny2 = y2 + dy2[i];
if(nx2 >= 1 && ny2 >= 1 && nx2 <= n && ny2 <= m && !st[nx2][ny2][1] && g[nx2][ny2] != '#'){
st[nx2][ny2][1] = true ;
if(st[nx2][ny2][0]) return time;
for(int j= 0; j < 4 ; j ++){
int nnx2 = nx2 +dx2[j],nny2 = ny2 + dy2[j];
if(nnx2 >= 1 && nny2 >= 1 && nnx2 <= n && nny2 <= m && !st[nnx2][nny2][1] && g[nnx2][nny2] != '#'){
st[nnx2][nny2][1] = true ;
if(st[nnx2][nny2][0]) return time;
q2.push({nnx2,nny2});
}
}
}
}
}
}
return -1;
}
int main(){
cin>>n>>m;
for(int i =1 ; i <= n ; i ++){
for(int j =1 ; j <= m ; j ++){
cin>>g[i][j];
if(g[i][j]=='C') sx1=i,sy1=j;
if(g[i][j]=='D') sx2=i,sy2=j;
}
}
int ans =bfs();
if(ans==-1) cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
cout<<ans<<endl;
}
// cout<<st[4][4][0]<<" "<<st[3][5][1];
}