標籤:while 逾時 string test math ++ 起點 bit limit
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 << ‘\n‘; return 0;}
Codeforces Round #516 Div2 D. Labyrinth