一.题目链接:
HDU-3085
二.题目大意:
给你一个 n × m 的图,图由以下符号组成.
'.' :空地
'X' :墙
'M' :男
'G' :女
'Z' :鬼
规则:
男、女、鬼 都可以向上下左右四个方向走
每秒男的可以走三步,女的走一步,墙不能走.
每秒每个鬼 会分出子鬼占领距离他单位长度 ≤ 2 的方格(包括墙)
若男 || 女 被鬼抓住,则 GG.
问男、女是否能相遇,若能,则输出所需时间,若不能,则输出 -1.
三.分析:
这题就是双向 BFS + 模拟.
详见代码吧.
四.代码实现:
#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-6
#define pi acos(-1.0)
#define ll long long int
using namespace std;
const int M = (int)8e2;
int n, m;
char mp[M + 5][M + 5];
bool vis[2][M + 5][M + 5];
struct node
{
int x;
int y;
};
struct node z[2];
struct node s1, s2;
queue <node> q[2];
int Move[4][2] = {
{0, 1}, {0, -1},
{1, 0}, {-1, 0}
};
bool check(node p, int step)
{
for(int i = 0; i < 2; ++i)
{
if((int)abs(p.x - z[i].x) + (int)abs(p.y - z[i].y) <= step * 2)///曼哈顿距离
return 0;
}
return 1;
}
bool bfs(int id, int step)
{
struct node p, t;
int len = q[id].size();
while((len--) > 0)
{
p = q[id].front();
q[id].pop();
if(!check(p, step))///因为是鬼先走,所以要考虑此时鬼是否会抓住 id
continue;
for(int i = 0; i < 4; ++i)
{
t = p;
t.x += Move[i][0];
t.y += Move[i][1];
if(t.x < 0 || t.x >= n || t.y < 0 || t.y >= m || vis[id][t.x][t.y] || mp[t.x][t.y] == 'X' || !check(t, step))
continue;
vis[id][t.x][t.y] = 1;
if(vis[!id][t.x][t.y])
return 1;
q[id].push(t);
}
}
return 0;
}
int solve()
{
for(int i = 0; i < 2; ++i)
{
while(!q[i].empty())
q[i].pop();
}
memset(vis, 0, sizeof(vis));
vis[0][s1.x][s1.y] = vis[1][s2.x][s2.y] = 1;
q[0].push(s1);
q[1].push(s2);
int step = 1;
while(!q[0].empty() || !q[1].empty())
{
for(int i = 0; i < 3; ++i)///男 1 秒走 3 步
{
if(bfs(0, step))
return step;
}
if(bfs(1, step))///女 1 秒走 1 步
return step;
step++;
}
return -1;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d %d", &n, &m);
int cnt = 0;
for(int i = 0; i < n; ++i)
{
///getchar();
scanf("%s", mp[i]);///换成注释中的输入 T 爆了!!!
for(int j = 0; j < m; ++j)
{
///scanf("%c", &mp[i][j])
if(mp[i][j] == 'M')
{
s1.x = i;
s1.y = j;
}
else if(mp[i][j] == 'G')
{
s2.x = i;
s2.y = j;
}
else if(mp[i][j] == 'Z')
{
z[cnt].x = i;
z[cnt].y = j;
cnt++;
}
}
}
int ans = solve();
printf("%d\n", ans);
}
return 0;
}