大意:小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; }