QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#393041#5112. Where Am I?shepherdWA 1ms3968kbC++208.6kb2024-04-18 05:28:122024-04-18 05:28:13

Judging History

你现在查看的是最新测评结果

  • [2024-04-18 05:28:13]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3968kb
  • [2024-04-18 05:28:12]
  • 提交

answer

#include <bits/stdc++.h>

#include <chrono>

#ifdef LLOCAL
#include "debug.h"
#else
#define var(...)
#define debugArr(...)
#endif

using namespace std;

#define len(a) static_cast<int>((a).size())
#define present(c, x) (c.find(x) != c.end())
#define printDecimal(d) std::cout << std::setprecision(d) << std::fixed

using ll = long long;
using ull = unsigned long long;
using ld = long double;
constexpr const int iinf = 1e9 + 7;
constexpr const ll inf = 1e18;
constexpr const ll mod = 1'000'000'007;

template <typename Fun>
class y_combinator_result {
  Fun fun_;

 public:
  template <typename T>
  explicit y_combinator_result(T&& fun) : fun_(std::forward<T>(fun)) {}

  template <typename... Args>
  decltype(auto) operator()(Args&&... args) {
    return fun_(std::ref(*this), std::forward<Args>(args)...);
  }
};
template <typename Fun>
decltype(auto) y_combinator(Fun&& fun) {
  return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun));
}

struct TrieNode {
  int num_s{0}, weight{0};
  vector<int> children;
  pair<int, int> last_start;
  TrieNode() : children(2, -1) {}
};

static constexpr const int dx[] = {-1, 0, 1, 0};
static constexpr const int dy[] = {0, 1, 0, -1};

int main() {
  std::ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> m >> n;
  vector<vector<int>> grid(n, vector<int>(m));
  for (int i = 0; i < n; i++) {
    string line;
    cin >> line;
    for (int j = 0; j < m; j++) {
      if (line[j] == 'X') grid[i][j] = 1;
    }
  }
  auto traverse_grid = [&](int x, int y) {
    int nptr = 0;
    int top = x, bottom = x, left = y, right = y;
    vector<pair<int, int>> compressed{make_pair(grid[x][y], 1)};
    for (int num_steps = 1; num_steps < n * m;) {
      switch (nptr) {
        case 0: {
          top--;
          for (int i = bottom - 1; i >= top && num_steps < n * m; i--) {
            if (i >= 0 && i < n && left >= 0 && left < m) {
              if (compressed.empty() ||
                  compressed.back().first != grid[i][left]) {
                compressed.emplace_back(grid[i][left], 1);
              } else {
                compressed.back().second++;
              }
              num_steps++;
            } else {
              if (compressed.empty() || compressed.back().first != 0) {
                compressed.emplace_back(0, 1);
              } else {
                compressed.back().second++;
              }
            }
          }
          break;
        }
        case 1: {
          right++;
          for (int i = left + 1; i <= right && num_steps < n * m; i++) {
            if (i >= 0 && i < m && top >= 0 && top < n) {
              if (compressed.empty() ||
                  compressed.back().first != grid[top][i]) {
                compressed.emplace_back(grid[top][i], 1);
              } else {
                compressed.back().second++;
              }
              num_steps++;
            } else {
              if (compressed.empty() || compressed.back().first != 0) {
                compressed.emplace_back(0, 1);
              } else {
                compressed.back().second++;
              }
            }
          }
          break;
        }
        case 2: {
          bottom++;
          for (int i = top + 1; i <= bottom && num_steps < n * m; i++) {
            if (i >= 0 && i < n && right >= 0 && right < m) {
              if (compressed.empty() ||
                  compressed.back().first != grid[i][right]) {
                compressed.emplace_back(grid[i][right], 1);
              } else {
                compressed.back().second++;
              }
              num_steps++;
            } else {
              if (compressed.empty() || compressed.back().first != 0) {
                compressed.emplace_back(0, 1);
              } else {
                compressed.back().second++;
              }
            }
          }
          break;
        }
        case 3: {
          left--;
          for (int i = right - 1; i >= left && num_steps < n * m; i--) {
            if (i >= 0 && i < m && bottom >= 0 && bottom < n) {
              if (compressed.empty() ||
                  compressed.back().first != grid[bottom][i]) {
                compressed.emplace_back(grid[bottom][i], 1);
              } else {
                compressed.back().second++;
              }
              num_steps++;
            } else {
              if (compressed.empty() || compressed.back().first != 0) {
                compressed.emplace_back(0, 1);
              } else {
                compressed.back().second++;
              }
            }
          }
          break;
        }
        default: {
          assert(false);
        }
      }
      nptr = (nptr + 1) % 4;
    }
    return compressed;
  };
  vector<vector<vector<pair<int, int>>>> moves(
      n, vector<vector<pair<int, int>>>(m));
  vector<pair<int, int>> left, right;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      moves[i][j] = traverse_grid(i, j);
      reverse(moves[i][j].begin(), moves[i][j].end());
      if (moves[i][j].back().first == 0)
        left.emplace_back(i, j);
      else
        right.emplace_back(i, j);
    }
  }
  vector<TrieNode> nodes(1);
  auto build_trie =
      y_combinator([&](auto self, int ptr, vector<pair<int, int>> l,
                       vector<pair<int, int>> r) -> void {
        // do interesting stuff in here
        if (!l.empty()) {
          vector<pair<int, int>> next_right, next_left;
          assert(nodes[ptr].children[0] == -1);
          nodes.emplace_back();
          nodes[ptr].children[0] = len(nodes) - 1;
          int min_dist = iinf;
          for (const auto& [i, j] : l) {
            min_dist = min(min_dist, moves[i][j].back().second);
          }
          nodes[nodes[ptr].children[0]].weight = min_dist;
          nodes[nodes[ptr].children[0]].num_s = len(l);
          for (const auto& [i, j] : l) {
            assert(moves[i][j].back().first == 0);
            moves[i][j].back().second -= min_dist;
            nodes[nodes[ptr].children[0]].last_start = make_pair(i, j);
            if (moves[i][j].back().second == 0) {
              moves[i][j].pop_back();
              if (!moves[i][j].empty()) next_right.emplace_back(i, j);
            } else {
              next_left.emplace_back(i, j);
            }
          }
          self(nodes[ptr].children[0], next_left, next_right);
        }
        if (!r.empty()) {
          vector<pair<int, int>> next_right, next_left;
          assert(nodes[ptr].children[1] == -1);
          nodes.emplace_back();
          nodes[ptr].children[1] = len(nodes) - 1;
          int min_dist = iinf;
          for (const auto& [i, j] : r) {
            min_dist = min(min_dist, moves[i][j].back().second);
          }
          nodes[nodes[ptr].children[1]].weight = min_dist;
          nodes[nodes[ptr].children[1]].num_s = len(r);
          for (const auto& [i, j] : r) {
            assert(moves[i][j].back().first == 1);
            moves[i][j].back().second -= min_dist;
            nodes[nodes[ptr].children[1]].last_start = make_pair(i, j);
            if (moves[i][j].back().second == 0) {
              moves[i][j].pop_back();
              if (!moves[i][j].empty()) next_left.emplace_back(i, j);
            } else {
              next_right.emplace_back(i, j);
            }
          }
          self(nodes[ptr].children[1], next_left, next_right);
        }
      });
  build_trie(0, left, right);
  int max_depth = 0;
  unordered_map<int, vector<pair<int, int>>> cnt;
  y_combinator([&](auto self, int curr, int depth) {
    if (nodes[curr].num_s == 1) {
      max_depth = max(max_depth, depth);
      cnt[depth].push_back(nodes[curr].last_start);
      return;
    }
    if (nodes[curr].children[0] != -1) {
      self(nodes[curr].children[0], depth + nodes[curr].weight);
    }
    if (nodes[curr].children[1] != -1) {
      self(nodes[curr].children[1], depth + nodes[curr].weight);
    }
  })(0, 0);
  double e = 0.0;
  for (const auto& [k, v] : cnt) {
    e += double(k * len(v)) / double(n * m);
  }
  printDecimal(3) << e << '\n' << max_depth << '\n';
  vector<pair<int, int>> furthest;
  for (const auto& elem : cnt[max_depth]) {
    furthest.emplace_back(elem.second + 1, n - elem.first);
  }
  sort(furthest.begin(), furthest.end(), [](auto x, auto y) {
    if (x.second != y.second) return x.second < y.second;
    return x.first < y.second;
  });
  for (const auto& [x, y] : furthest) {
    cout << "(" << x << "," << y << ") ";
  }
  cout << '\n';
}

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 3772kb

input:

1 1
X

output:

0.000
0
(1,1) 

result:

ok correct!

Test #2:

score: 0
Accepted
time: 0ms
memory: 3828kb

input:

2 1
.X

output:

0.000
0
(1,1) (2,1) 

result:

ok correct!

Test #3:

score: -100
Wrong Answer
time: 1ms
memory: 3968kb

input:

2 1
X.

output:

0.000
0
(2,1) (1,1) 

result:

wrong answer Read (2,1) but expected (1,1)