Codeforces Round #516 Div2 D. Labyrinth
Posted hfccccccccccccc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #516 Div2 D. Labyrinth相关的知识,希望对你有一定的参考价值。
https://codeforces.com/contest/1064/problem/D
比赛时先交了个能 AC 的代码,之后感觉 vector
会超时,然后重交了一份,开了个很大的静态数组,system test 时直接爆了 ML。
不过赛后说什么也没用了对吧。。。
题意
有一个迷宫,你可以上下左右走,但是要求左走的次数不超过 (x),右走的次数不超过 (y),问有多少个点能从起点到达。
题解
比赛时瞪了一会儿样例随便 yy 了个贪心,但是不会证。。。
一个点能被到达,当且仅当存在一条向左次数不超过 (x) 的路径,向右次数不超过 (y) 的路径。。。是不是听起来很假啊。。。
直接跑 Dijkstra 貌似比较虚,用基数堆可以硬怼过去。
但是我个傻 x 没注意到边权只有 (0) 和 (1),直接双端队列跑 BFS 即可。。。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m, r, c, bl, br;
cin >> n >> m >> r >> c >> bl >> br;
r--;
c--;
vector<string> board(n);
for (int i = 0; i < n; i++) {
cin >> board[i];
}
auto get_id = [&](int x, int y) {
return x * m + y;
};
vector< vector< pair<int, pair<int, int> > > > g(n * m);
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
for (int x = 0; x < n; x++) {
for (int y = 0; y < m; y++) {
if (board[x][y] == ‘*‘) {
continue;
}
int me = get_id(x, y);
for (int k = 0; k < 4; k++) {
int xk = x + dx[k];
int yk = y + dy[k];
if (xk < 0 || xk >= n || yk < 0 || yk >= m || board[xk][yk] == ‘*‘) {
continue;
}
int him = get_id(xk, yk);
g[me].push_back({him, {k == 3, k == 1}});
}
}
}
deque<int> q;
q.push_back(get_id(r, c));
const int inf = numeric_limits<int>::max();
vector<int> dist(n * m, inf);
dist[get_id(r, c)] = 0;
while (!q.empty()) {
int v = q.front();
int d = dist[v];
q.pop_front();
for (auto &e : g[v]) {
int u = e.first;
int w = e.second.first;
if (dist[u] <= d + w) {
continue;
}
if (w == 0) {
q.push_front(u);
dist[u] = d;
} else {
q.push_back(u);
dist[u] = d + 1;
}
}
}
vector<char> alive(n * m);
for (int i = 0; i < n * m; i++) {
alive[i] = (dist[i] <= bl);
}
q.push_back(get_id(r, c));
fill(dist.begin(), dist.end(), inf);
dist[get_id(r, c)] = 0;
while (!q.empty()) {
int v = q.front();
int d = dist[v];
q.pop_front();
for (auto &e : g[v]) {
int u = e.first;
int w = e.second.second;
if (dist[u] <= d + w) {
continue;
}
if (w == 0) {
q.push_front(u);
dist[u] = d;
} else {
q.push_back(u);
dist[u] = d + 1;
}
}
}
int ans = 0;
for (int i = 0; i < n * m; i++) {
if (alive[i] && dist[i] <= br) {
ans++;
}
}
cout << ans << ‘
‘;
return 0;
}
以上是关于Codeforces Round #516 Div2 D. Labyrinth的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #516 (Div. 2, by Moscow Team Olympiad)
Codeforces Round #516 (Div. 1) 题解
Codeforces Round #516 Div2 D. Labyrinth
Codeforces Round #516 (Div. 1, by Moscow Team Olympiad) D