代码思想:
每秒对小B进行两次BFS,对小A进行一次BFS,当他们碰见对方走过的路就跳出循环输出此时时间即可,具体可见代码。
时间复杂度:O(nm)
代码部分:
#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; }