蓝书(算法竞赛进阶指南)刷题记录——hdu3085 Nightmare2(双向bfs)

版权声明:转载请注明原出处啦QAQ(虽然应该也没人转载): https://blog.csdn.net/hzk_cpp/article/details/89787030

题目:hdu3085.
题目大意:给定一个 n m n*m 的网格,网格上有一对男女和两个鬼,男孩每秒钟最多走三格,女孩每秒钟最多走一格,鬼在第 t t 秒会占领所有曼哈顿距离它 2 t 2t 以内的格子,求男孩和女孩最快多久可以相遇且不经过鬼占领的区域.
1 n , m 800 1\leq n,m\leq 800 .

双向bfs的入门题,感觉没什么好说的,但作为板子还是说一点吧…

大家都知道双向bfs的原理,这里就说一点实现细节.可以用两个队列直接男孩和女孩的状态,把每一次拓展都写成一个函数,男孩拓展的时候调用三次这个函数,女孩拓展的时候调用一次,鬼可以直接用时间判,其它应该就没什么了…

代码如下:

#include<bits/stdc++.h>
  using namespace std;

#define Abigail inline void
typedef long long LL;

const int N=800;
const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};

char Rc(){
  char c=getchar();
  while (c^'.'&&(c<'A'||c>'Z')) c=getchar();
  return c;
}

int n,m;
char b[N+9][N+9];
struct node{
  int x,y;
  node(int X=0,int Y=0){x=X;y=Y;} 
}gh[2],M,G;

bool Catch(node x,int t){
  if (abs(x.x-gh[0].x)+abs(x.y-gh[0].y)<=t<<1) return 1;
  if (abs(x.x-gh[1].x)+abs(x.y-gh[1].y)<=t<<1) return 1;
  return 0;
}

queue<node>q[2];
bool vis[2][N+9][N+9];

bool Bfs(int id,int tm){
  int siz=q[id].size();
  node t,nt;
  while (siz--){
  	t=q[id].front();q[id].pop();
  	if (Catch(t,tm)) continue;
  	for (int i=0;i<4;++i){
	  nt=node(t.x+dx[i],t.y+dy[i]);
	  if (nt.x<1||nt.x>n||nt.y<1||nt.y>m) continue;
	  if (b[nt.x][nt.y]=='X'||b[nt.x][nt.y]=='Z') continue;
	  if (vis[id][nt.x][nt.y]) continue;
	  if (Catch(nt,tm)) continue;
	  vis[id][nt.x][nt.y]=1;
	  if (vis[id^1][nt.x][nt.y]) return 1;
	  q[id].push(nt);
	}
  }
  return 0;
}

int Solve(){
  for (int i=1;i<=n;++i)
    for (int j=1;j<=m;++j)
      vis[0][i][j]=vis[1][i][j]=0;
  for (int i=0;i<2;++i)
    while (!q[i].empty()) q[i].pop(); 
  vis[0][M.x][M.y]=1;
  vis[1][G.x][G.y]=1;
  q[0].push(M);
  q[1].push(G);
  int tm=0;
  while (!q[0].empty()||!q[1].empty()){
    ++tm;
    for (int i=0;i<3;++i)
      if (Bfs(0,tm)) return tm;
    if (Bfs(1,tm)) return tm;
  }
  return -1;
}

Abigail into(){
  scanf("%d%d",&n,&m);
  int cgh=0;
  for (int i=1;i<=n;++i)
    for (int j=1;j<=m;++j){
      b[i][j]=Rc();
      if (b[i][j]=='Z') gh[cgh].x=i,gh[cgh++].y=j;
      if (b[i][j]=='M') M.x=i,M.y=j;
      if (b[i][j]=='G') G.x=i,G.y=j;
    }
}

Abigail outo(){
  printf("%d\n",Solve()); 
}

int main(){
  int T;
  scanf("%d",&T);
  while (T--){
    into();
    outo();
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/hzk_cpp/article/details/89787030