小A与小B-(双向bfs)

链接:https://ac.nowcoder.com/acm/contest/549/G
来源:牛客网

题目描述

小A与小B这次两个人都被困在了迷宫里面的两个不同的位置,而他们希望能够迅速找到对方,然后再考虑如何逃离迷宫的事情。小A每次可以移动一个位置,而小B每次可以移动两次位置,小A移动的方向是上下左右左上左下右上右下8个方向,小B移动的方向是上下左右4个方向,请问他们最早什么时候能够找到对方,如果他们最终无法相遇,那么就输出”NO"。

输入描述:

第一行两个整数N,M分别表示迷宫的行和列。接下来一个N×M的矩阵其中"C"表示小A的位置,"D"表示小B的的位置,"#"表示不可通过的障碍,"."则是可以正常通过的位置。字符用空格隔开第一行两个整数N,M分别表示迷宫的行和列。接下来一个N×M的矩阵其中"C"表示小A的位置,"D"表示小B的的位置,"#"表示不可通过的障碍,"."则是可以正常通过的位置。字符用空格隔开

输出描述:

如果可以相遇,第一行输出一个YES,第二行一个整数输出最短的相遇时间。
否则就输出一个NO表示不能相遇。
示例1

输入

4 5
. . . . .
. # # # .
. . . # D
. . C # .

输出

YES
3

备注:

1≤n,m≤1000

解题:
首次遇到地图里两个人的,显然用两次bfs,而且其中一个人不是简简单单每次走一步,而是每次走两步,个人感觉变动有点大,驾驭不住,就写了两个bfs函数,我看大牛们一个就够了,用参数解决。
用三维数组表示不同人的走路步数,一边判断是否走过,顺便标记步数。
最后遍历地图,取二者都能走到的位置,取二人步数大者为答案,动态找较大者的最小值。
 #include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std; struct node
{
int x;
int y;
};
int n,m,ans;
int ax,ay,bx,by,cnt;
char mp[][];
int vis[][][];///判断是否走过,顺便记录走到这一步的步数
int d0[][]={-,-, -,, -,, ,-, ,, ,-, ,, ,};///A的位移
int d1[][]={-,, ,, ,-, ,};///B的位移
queue<node>que[];///0表示A,1表示B void bfs0()
{
while(!que[].empty()) que[].pop();
que[].push( {ax,ay} );
while(!que[].empty())
{
node now=que[].front();
int cnt=vis[][now.x][now.y];///走到这一步的步数
que[].pop();
for(int i=;i<;i++)
{
int xx=now.x+d0[i][];
int yy=now.y+d0[i][];
if( xx>= && xx<=n && yy>= && yy<=m && mp[xx][yy]=='.' && vis[][xx][yy]==- )
{
que[].push( {xx,yy} );
vis[][xx][yy]=cnt+;///位移+1
}
}
}
} void bfs1()
{
while(!que[].empty()) que[].pop();
que[].push( {bx,by} );
while(!que[].empty())
{
node now=que[].front();
que[].pop();
int cnt=vis[][now.x][now.y];
for(int i=;i<;i++)///第一步
{
int xx=now.x+d1[i][];
int yy=now.y+d1[i][];
if(xx>= && xx<=n && yy>= && yy<=m && mp[xx][yy]=='.' && vis[][xx][yy]==- )
{
vis[][xx][yy]=cnt+;///第一步也要记录位移次数,与第二步的次数一样
for(int j=;j<;j++)///第二步在if大括号里,否则会窗墙
{
int tx=xx+d1[j][];
int ty=yy+d1[j][]; if( tx>= && tx<=n && ty>= && ty<=m && mp[tx][ty]=='.' && vis[][tx][ty]==- )
{
que[].push( {tx,ty} );
vis[][tx][ty]=cnt+;///位移次数+1
}
}
}
}
}
} int main()
{
memset(vis,-,sizeof(vis));
scanf("%d %d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
cin>>mp[i][j];
if(mp[i][j]=='C') ax=i,ay=j;
if(mp[i][j]=='D') bx=i,by=j;
}
vis[][ax][ay]=;
vis[][bx][by]=;///起点为0
bfs0();
bfs1();
/**打印观察
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%2d ",vis[0][i][j]);
printf("\n");
}
printf("\n\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%2d ",vis[1][i][j]);
printf("\n");
}
*/
int ans=inf;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
if( vis[][i][j]!=- && vis[][i][j]!=- )
ans = min( max(vis[][i][j],vis[][i][j]), ans );
}
if(ans!=inf)
printf("YES\n%d\n",ans);
else
printf("NO\n");
return ;
}

上一篇:java多线程基础(synchronize关键字)


下一篇:Python练习题