前言:这个答案给我们提供了一种多次dfs的思路,记录queue的size,每次只取size个,就刚刚好只处理了上一次的‘
题目地址
#include<bits/stdc++.h>
using namespace std;
//定义队列节点
struct node
{
int x,y;
}rear,front;
//Q[0]为小B进行BFS的队列,Q[1]为小A进行BFS的队列
queue<node>Q[2];
//ans表示双方碰面时间
int ans=0,N,M,dx[]={0,0,1,-1,1,1,-1,-1},dy[]={1,-1,0,0,1,-1,1,-1};
char R[1005][1005];
//Flag表示是否能碰面,V[0][][]为小B的标记数组,V[1][][]为小A的标记数组
bool Flag=0,V[2][1005][1005]={0};
//参数a为0表示小B进行BFS,为1则是小A进行BFS
bool BFS(bool a)
{
int i,x,y,q=Q[a].size();
//将该时刻能走到的所有位置出队搜索
while(q--)
{
front=Q[a].front(),Q[a].pop();
//若a为1,那么小A要进行8个方向的搜索
for(i=0;i<4+(a?4:0);i++)
{
x=front.x+dx[i],y=front.y+dy[i];
//越界或者碰见障碍或者走回头路都是非法的
if(x<0||x>=N||y<0||y>=M||R[x][y]=='#'||V[a][x][y])continue;
//若碰见对方走过的路,令Flag置1,同时返回1
if(V[!a][x][y])return Flag=1;
//下个位置入队
V[a][x][y]=1,rear.x=x,rear.y=y,Q[a].push(rear);
}
}
//若未碰见对方,返回0
return 0;
}
int main()
{
int i,j,x1,y1,x2,y2;
scanf("%d%d",&N,&M);
//接收地图,记录小A与小B的起点
for(i=0;i<N;i++)
for(j=0;j<M;j++)
{
scanf(" %c",&R[i][j]);
if(R[i][j]=='D')x1=i,y1=j;
if(R[i][j]=='C')x2=i,y2=j;
}
rear.x=x1,rear.y=y1,V[0][x1][y1]=1,Q[0].push(rear);
rear.x=x2,rear.y=y2,V[1][x2][y2]=1,Q[1].push(rear);
//每秒小B进行BFS两次,而小A进行BFS一次
while(!Q[0].empty()||!Q[1].empty())
{
ans++;
//一旦碰到对方立马跳出循环
if(BFS(0))break;
if(BFS(0))break;
if(BFS(1))break;
}
if(Flag)printf("YES\n%d\n",ans);
else printf("NO\n");
return 0;
}