码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #516 Div2 D. Labyrinth

时间:2018-10-14 23:36:14      阅读:313      评论:0      收藏:0      [点我收藏+]

标签: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

标签:while   超时   string   test   math   ++   起点   bit   limit   

原文地址:https://www.cnblogs.com/hfccccccccccccc/p/9788693.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!