大意:小A小B从两个点出发,想尽快相见,求最短时间。
思路: 同时对小A和小B进行bfs,相遇了就直接输出,一直遇不到就是NO,详细的写到注释里了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
#define mod 1000000007
using namespace std;
int n,m,ax,ay,bx,by;
struct node{
int a,b;
char m;
}maps[1005][1005]; ///a,b用来记录他们是否走过这里,m用来记录地图的#和.
struct que{
int x,y;
}pa,pb;
queue<que> a,b;
int bfs()
{
///把小A和小B的起点存到队列a和b里
pa.x=ax,pa.y=ay;
a.push(pa);
maps[ax][ay].a=1;
pb.x=bx,pb.y=by;
b.push(pb);
maps[bx][by].b=1;
int time=1; ///记录时间
int xx[]={0,0,1,-1,1,1,-1,-1},yy[]={1,-1,0,0,-1,1,-1,1};
while(time)
{
int len=a.size();
while(len--){ ///将上次存到队列里的走完
pa=a.front();a.pop();
for(int i=0;i<8;++i)
{
int xa=pa.x+xx[i], ya=pa.y+yy[i]; ///下一步的坐标
if(maps[xa][ya].m=='#' || xa<1 ||xa>n ||ya<1 ||ya>m || maps[xa][ya].a==1)
continue;
maps[xa][ya].a=1;
a.push({xa,ya});
if(maps[xa][ya].b==1) ///如果b走过这里说明可以相遇了,直接返回时间输出
return time;
}
}
for(int t=1;t<=2;++t){ ///小B可以走两次
len=b.size();
while(len--){
pb=b.front();b.pop();
for(int i=0;i<4;++i)
{
int xb=pb.x+xx[i], yb=pb.y+yy[i];
if(maps[xb][yb].m=='#' || xb<1 ||xb>n ||yb<1 ||yb>m || maps[xb][yb].b==1)
continue;
maps[xb][yb].b=1;
b.push({xb,yb});
if(maps[xb][yb].a==1)
return time;
}
}
}
time++;
}
return 0;
}
int main ()
{
int i,t,j,k;
cin>>n>>m;
for(i=1;i<=n;++i)
for(t=1;t<=m;++t){
cin>>maps[i][t].m;
if(maps[i][t].m=='C')
ax=i,ay=t;
if(maps[i][t].m=='D')
bx=i,by=t;
}
k=bfs();
if(k)
cout<<"YES"<<endl<<k<<endl;
else
cout<<"NO"<<endl;
return 0;
}

京公网安备 11010502036488号