题意:小A与小B被困在一个n*m的迷宫中,'.'为可通过,'#'为障碍不可通过,'C'为小A初始位置,'D'为小B初始位置。小A可以上下左右左上左下右上右下8个方向移动,而小B只能上下左右移动,不过小B能一秒移动二次,而小A只能一秒移动一次。求小A与小B最早什么时候相遇?不能相遇只输出NO.
思路:分别bfs小A和小B,求出分别到达每一个位置的最早时间,初始时间为inf(一个很大的数),一个位置的相遇时间为二个到达时间的最大值,求所有位置相遇的最小值。
代码:
#include<bits/stdc++.h>
#define ll long long
#define inf 100000007
using namespace std;
int n, m;
char s[1005][1005];
int dc[1005][1005], dd[1005][1005], xc, yc, xd, yd, dx[9]= {1,-1,0,0,-1,-1,1,1}, dy[9]= {0,0,1,-1,1,-1,1,-1};
struct w
{
int x, y;
} w, w1;
void bfsc()
{
queue<struct w> q;
w.x=xc;
w.y=yc;
q.push(w);
fill(dc[0],dc[0]+1005*1005,inf);
dc[w.x][w.y]=0;
while(!q.empty())
{
w=q.front();
q.pop();
for(int i=0; i<8; i++)
{
w1.x=w.x+dx[i];
w1.y=w.y+dy[i];
if(w1.x>=0&&w1.x<n&&w1.y>=0&&w1.y<m&&dc[w1.x][w1.y]==inf&&s[w1.x][w1.y]!='#')
{
dc[w1.x][w1.y]=dc[w.x][w.y]+1;
q.push(w1);
}
}
}
}
void bfsd()
{
queue<struct w> q;
w.x=xd;
w.y=yd;
q.push(w);
fill(dd[0],dd[0]+1005*1005,2*inf);
dd[w.x][w.y]=0;
while(!q.empty())
{
w=q.front();
q.pop();
for(int i=0; i<4; i++)
{
w1.x=w.x+dx[i];
w1.y=w.y+dy[i];
if(w1.x>=0&&w1.x<n&&w1.y>=0&&w1.y<m&&dd[w1.x][w1.y]==2*inf&&s[w1.x][w1.y]!='#')
{
dd[w1.x][w1.y]=dd[w.x][w.y]+1;
q.push(w1);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
getchar();
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
scanf("%c",&s[i][j]);
if(s[i][j]=='C')
{
xc=i;
yc=j;
}
if(s[i][j]=='D')
{
xd=i;
yd=j;
}
if(j!=m-1)
getchar();
}
if(i!=n-1)
{
getchar();
}
}
bfsc();
bfsd();
int z=inf;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
z=min(z,max(dc[i][j],(dd[i][j]+1)/2));
}
}
if(z!=inf)
cout << "YES" << "\n" << z << endl;
else
cout << "NO" << endl;
return 0;
}

京公网安备 11010502036488号