QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#393041 | #5112. Where Am I? | shepherd | WA | 1ms | 3968kb | C++20 | 8.6kb | 2024-04-18 05:28:12 | 2024-04-18 05:28:13 |
Judging History
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';
}
Details
Tip: Click on the bar to expand more detailed information
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)