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