Link
解题思路
ybtoj交完心平气和,两天后杭州oj交完心态爆炸
这件事教会了zzl打题要用快读
鬼的覆盖范围不需要特别处理,只需要O(1)判断一下走没走到鬼的覆盖范围
接下来就是boy & girl了,
每秒boy走三步,girl走一步就很迷: )
他俩必须同时BFS,但是是两个不同的队列
那么boy直接就加一层循环寻三步就欧克了
boy走到的点标记为1,girl走过的点标记为2,那么1和2第一次出现同一格时就是会和了
STL——pair函数
新学的一个函数
(个人理解)
就是把两个元素绑在一起(类似一个struct node{int first, second;};)
- 定义
#include <iostream>
#include <cstdio>
*#include <utility>*
using namespace std;
pair<int, int> a;
pair<string, int> b;
一个pair<>里面可以放两个元素
比如:a里面可以放两个int,b里面first放string类型,second放int类型
- 小用法
pair<int, int> now;
int a, b;
now = make_pair(a, b);
make_pair可以将两个。。变量(?)合(?)成一个pair
Code
#include <iostream>
#include <utility>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
const int way[4][2] = {
{
-1, 0}, {
1, 0}, {
0, -1}, {
0, 1}};
queue< pair<int, int> > q_boy, q_girl;
pair<int, int> ghost[2], now;
int T, n, m, xx, yy, v[810][810];
char a[810][810];
inline int read() {
//什么神仙题目,数据有毒就直接把快读贴出来
int x = 0, f = 1; char s = getchar();
while (s < '0' || s > '9') {
if (s == '-') f = -f; s = getchar(); }
while (s >= '0' && s <= '9') {
x = x * 10 + s - '0'; s = getchar(); }
return x * f;
}
char readc() {
//什么垃圾题目,不是说不想用快读去杭州oj交吗,为什么不加快读就超时
char c = getchar();
while((c > 'Z' || c < 'A') && c != '.') c = getchar();
return c;
}
bool check(int x, int y, int min) {
if (x < 1 || x > n || y < 1 || y > m || a[x][y] == 'X')
return 0;
for (int i = 0; i < 2; i++)
if ((abs(x - ghost[i].first) + abs(y - ghost[i].second)) <= 2 * min)//判断有没有走到鬼覆盖范围
return 0;
return 1;
}
void BFS() {
int min = 0;//记录时间
while(!q_boy.empty() || !q_girl.empty()) {
min++;
for (int step = 1; step <= 3; step++)//boy走3步
for (int oie = q_boy.size(); oie; oie--) {
//因为中途会push进一些点,所以必须倒序
now = q_boy.front();
q_boy.pop();
if (!check(now.first, now.second, min))
continue;
for (int i = 0; i < 4; i++) {
xx = now.first + way[i][0], yy = now.second + way[i][1];
if (!check(xx, yy, min))
continue;
if (v[xx][yy] != 1) {
//boy没走过
if (v[xx][yy] == 2) {
//girl走过这个点
printf("%d\n", min);
return;
}
q_boy.push(make_pair(xx, yy));
v[xx][yy] = 1;
}
}
}
for (int oie = q_girl.size(); oie; oie--) {
//girl同上
now = q_girl.front();
q_girl.pop();
if (!check(now.first, now.second, min))
continue;
for (int i = 0; i < 4; i++) {
xx = now.first + way[i][0], yy = now.second + way[i][1];
if (!check(xx, yy, min))
continue;
if (v[xx][yy] != 2) {
if (v[xx][yy] == 1) {
printf("%d\n", min);
return;
}
q_girl.push(make_pair(xx, yy));
v[xx][yy] = 2;
}
}
}
}
printf("-1\n");
}
int main() {
T = read();
while (T--) {
memset(v, 0, sizeof(v));
while(!q_boy.empty())
q_boy.pop();
while(!q_girl.empty())
q_girl.pop();
n = read(), m = read();
int cnt = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = readc();//(怒 ̄へ ̄)
if (a[i][j] == 'Z')
ghost[cnt++] = make_pair(i, j);//记录鬼的位置
if (a[i][j] == 'M') {
q_boy.push(make_pair(i, j));//将boy放进boy的队列里
v[i][j] = 1;//标记为boy走过的点
}
if (a[i][j] == 'G') {
q_girl.push(make_pair(i, j));//将girl放进girl的队列里
v[i][j] = 2;//标记为girl走过的点
}
}
}
BFS();
}
}