洛谷P9116 题解
本题解亮点:
- 不需要双向广搜。
- 用普及组方法也能做!
大致思路
-
bfs 蜜蜂在各个时间点会到达的地方。
-
二分答案,枚举小熊等待时长。
具体实现
-
读入地图。
-
进行第一轮 bfs,求蜜蜂占领各个点需要的时间。我们先将所有蜜蜂的初始位置加入队列,随后再把相邻的单元格入队。
-
二分小熊等待时长。每一次二分校验时,需要再跑一次 bfs,而且 bfs 时要设一个时间戳,每到一个点,看他是否超时。对于 \(l\) 和 \(r\),如果 \(mid\) 合法,则将 \(l\) 赋值为 \(mid\),否则将 \(r\) 赋值为 \(mid-1\),
OK,我们可以开始愉快地写代码了(本蒟蒻代码暴丑,大佬勿喷)
#include <bits/stdc++.h>
#define array(x, j) \
for (int i = 0; i < j; i++) cout << x[i] << " ";
#define ln cout << endl;
#define rpp(i, n) for (int i = 1; i <= n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define bk(i, st, ed) for (int i = st; i >= ed; i--)
#define debug(x) cout << #x << " : " << x << " , on line " << __LINE__ << endl;
#define pb push_back
#define pf push_front
#define iter iterator
#define fi first
#define se second
#define ll long long
using namespace std;
void file(string x) {
freopen((x + ".in").c_str(), "r", stdin);
freopen((x + ".out").c_str(), "w", stdout);
}
inline int read() {
int f = 1, s = 0;
char c = getchar();
for (; (c < '0' || c > '9') && c != '-'; c = getchar())
;
if (c == '-') {
f = -1;
c = getchar();
}
for (; c >= '0' && c <= '9'; c = getchar()) s = (s << 1) + (s << 3) + c - 48;
return s * f;
}
void FastIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
template <class Tp>
inline void input(Tp &x) {
cin >> x;
}
template <class Tp, class... Oth>
inline void input(Tp &x, Oth &... y) {
input(x), input(y...);
}
template <class Tp>
inline void print(Tp x) {
cout << x << " ";
};
template <class Tp, class... Oth>
inline void print(Tp x, Oth... y) {
print(x), print(y...), cout << endl;
}
const int N = 805;
const int dx[] = { -1, 1, 0, 0 };
const int dy[] = { 0, 0, -1, 1 };
char mp[N][N];
bool vis[N][N];
int t[N][N];
int n, s;
struct pos {
int x, y;
};
struct node {
int x, y, stp, used;
};
vector<pos> bee;
pos st;
pos ed;
inline bool chk(int x, int y) {
return x > 0 and x <= n and y > 0 and y <= n and mp[x][y] != 'T' and mp[x][y] != 'D';
}
inline bool chk1(int x, int y, int z) {
return x > 0 and x <= n and y > 0 and y <= n and !vis[x][y] and t[x][y] > z;
}
void bfs() {
memset(t, -1, sizeof(t));
queue<node> q;
rep(i, bee.size()) {
q.push({ bee[i].x, bee[i].y, 0 });
t[bee[i].x][bee[i].y] = 0;
}
while (!q.empty()) {
auto cur = q.front();
q.pop();
int x = cur.x;
int y = cur.y;
rep(i, 4) {
int xx = x + dx[i];
int yy = y + dy[i];
if (chk(xx, yy) and t[xx][yy] == -1) {
t[xx][yy] = cur.stp + 1;
q.push({ xx, yy, cur.stp + 1 });
}
}
}
}
bool calc(int x) {
memset(vis, 0, sizeof(vis));
queue<node> q;
if (t[st.x][st.y] <= x)
return false;
q.push({ st.x, st.y, x, 0 });
vis[st.x][st.y] = 1;
while (!q.empty()) {
auto cur = q.front();
q.pop();
int x = cur.x;
int y = cur.y;
if (cur.x == ed.x and cur.y == ed.y) {
return true;
}
rep(i, 4) {
int xx = x + dx[i];
int yy = y + dy[i];
if (cur.used + 1 == s) {
if (chk1(xx, yy, cur.stp + 1) or (ed.x == xx and ed.y == yy)) {
q.push({ xx, yy, cur.stp + 1, 0 });
vis[xx][yy] = 1;
}
} else {
if (chk1(xx, yy, cur.stp) or (ed.x == xx and ed.y == yy)) {
q.push({ xx, yy, cur.stp, cur.used + 1 });
vis[xx][yy] = 1;
}
}
}
}
return false;
}
int main() {
input(n, s);
rpp(i, n) {
scanf("%s", mp[i] + 1);
rpp(j, n) {
if (mp[i][j] == 'M') {
st = { i, j };
}
if (mp[i][j] == 'D') {
ed = { i, j };
}
if (mp[i][j] == 'H') {
bee.pb((pos){ i, j });
}
}
}
bfs();
int l = 0, r = n * n;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (calc(mid)) {
l = mid;
} else {
r = mid - 1;
}
}
if (calc(l)) {
print(l);
} else {
print(-1);
}
return 0;
}
本文来自博客园,作者:XSS_Worm,转载请注明原文链接:https://www.cnblogs.com/xss-worm/p/18445653

浙公网安备 33010602011771号