提出 #70123223
ソースコード 拡げる
#pragma GCC target("arch=skylake-avx512")
#pragma GCC optimize("O3","inline")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma,avx512f")
// #include <atcoder/dsu>
// #include <atcoder/segtree>
// #include <atcoder/mincostflow>
#include <immintrin.h>
#define FINAL_SUBMIT 1
#include <algorithm>
#include <array>
#include <bit>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(x) (x).begin(), (x).end()
#if FINAL_SUBMIT
#define HHH(x)
#define LOG(x)
#define FORCE_LOG(x) std::cerr << #x << " = " << x << "\n"
#define GRAPH(x, y)
#define CERR() if (false) std::cerr
#define NDEBUG
#else
#define HHH(x) std::cerr << "L" << __LINE__ << ": " << #x << " : " << (x) << "\n"
#define LOG(x) std::cerr << #x << " = " << x << "\n"
#define FORCE_LOG(x) std::cerr << #x << " = " << x << "\n"
#define GRAPH(x, y) std::cerr << "graph " << x << " " << y << "\n"
#define CERR() std::cerr
#endif
template <typename T> T &chmin(T &a, const T &b) { return a = std::min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = std::max(a, b); }
using ll = long long;
using ld = double;
constexpr int INF = 1e9;
constexpr double PI = acos(-1.0);
template <typename T> T sq(T x) { return x * x; }
template <typename T, typename U>
std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& p) {
return os << "(" << p.first << ", " << p.second << ")";
}
template <typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
os << "[";
for (const T& e : vec) os << " " << e;
os << " ]";
return os;
}
class Timer {
public:
static constexpr int64_t CYCLES_PER_SEC = 2900000000;
int64_t start, stop;
inline int64_t get_cycle() const {
uint32_t low, high;
__asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
return int64_t(low) | (int64_t(high) << 32);
}
Timer(double time_limit) : start(get_cycle()), stop(start + CYCLES_PER_SEC * time_limit) {}
inline void reset_stop(double time_limit) { stop = start + CYCLES_PER_SEC * time_limit; }
inline bool within(int64_t end) const { return get_cycle() < end; }
inline bool within() const { return within(stop); }
inline double elapsed() const { return (get_cycle() - start) / double(CYCLES_PER_SEC); }
};
class XorShift {
unsigned int x, y, z, w;
public:
XorShift() : x(314159265), y(358979323), z(846264338), w(327950288) {}
inline unsigned int next() {
unsigned int t = x ^ x << 11;
x = y; y = z; z = w;
return w = w ^ w >> 19 ^ t ^ t >> 8;
}
inline int next(int n) { return next() % n; }
inline int next(size_t n) { return next() % n; }
inline int next(int lo, int hi) { return lo + next(hi - lo + 1); }
inline double next(double x) { return double(next()) / (1LL << 32) * x; }
inline double next(double lo, double hi) { return lo + next(hi - lo); }
};
double get_param(const char* env_var) {
char* ret = getenv(env_var);
assert (ret != nullptr);
return stod(std::string(ret));
}
// double a_param = get_param("A_PARAM");
// double b_param = get_param("B_PARAM");
// double c_param = get_param("C_PARAM");
// int a_param = get_param("A_PARAM");
// int j_param = get_param("J_PARAM");
constexpr double TIME_LIMIT = 2.0;
Timer timer(TIME_LIMIT * 0.99);
XorShift rnd;
using namespace std;
int N, Si, Sj, Ti, Tj;
constexpr int C = 42;
bool A[C][C];
int S, T;
alignas(64) static uint32_t GDIST_S[C * C];
static uint16_t GDIST_EPOCH = 1;
inline int DistFromSIdx(int v) {
uint32_t x = GDIST_S[v];
return (uint16_t)(x >> 16) == GDIST_EPOCH ? int(x & 0xFFFFu) : 0;
}
void SetUp() {
cin >> N >> Ti >> Tj;
Si = 0; Sj = N / 2;
REP(i,N) {
string line;
cin >> line;
REP(j,N) A[i][j] = (line[j] == 'T');
}
LOG(N);
LOG(Ti);
LOG(Tj);
S = (Si + 1) * C + (Sj + 1);
T = (Ti + 1) * C + (Tj + 1);
}
struct Board {
int sol_type = 0;
int n_plot = -1;
vector<int> path;
alignas(64) int8_t B[C * C]; // size C*C
void Init() {
std::fill(B, B + C * C, 1);
REP(i,N) REP(j,N) B[(i+1)*C+j+1] = A[i][j] ? 1 : 0;
}
vector<int> ShortestPath(int s, int t) const {
alignas(64) static uint16_t seen[C * C];
alignas(64) static uint16_t dist[C * C];
alignas(64) static int prevv[C * C];
alignas(64) static int q[C * C];
static uint16_t stamp = 1;
if (++stamp == 0) {
memset(seen, 0, sizeof(seen));
stamp = 1;
}
static constexpr int dx[4] = {1, -1, C, -C};
static constexpr uint8_t PERM[12][4] = {
{0,1,2,3},{0,2,1,3},{0,3,1,2},{1,0,2,3},{1,2,0,3},{1,3,0,2},
{2,0,1,3},{2,1,0,3},{2,3,0,1},{3,0,1,2},{3,1,0,2},{3,2,0,1}
};
const uint8_t* ord = PERM[rnd.next() % 12];
int qh = 0, qt = 0;
q[qt++] = t;
seen[t] = stamp;
dist[t] = 0;
prevv[t] = -1;
while (qh < qt) {
const int v = q[qh++];
if (v == s) break;
const uint16_t nd = dist[v] + 1;
int u = v + dx[ord[0]];
if (!B[u] && seen[u] != stamp) {
seen[u] = stamp; dist[u] = nd; prevv[u] = v; q[qt++] = u;
}
u = v + dx[ord[1]];
if (!B[u] && seen[u] != stamp) {
seen[u] = stamp; dist[u] = nd; prevv[u] = v; q[qt++] = u;
}
u = v + dx[ord[2]];
if (!B[u] && seen[u] != stamp) {
seen[u] = stamp; dist[u] = nd; prevv[u] = v; q[qt++] = u;
}
u = v + dx[ord[3]];
if (!B[u] && seen[u] != stamp) {
seen[u] = stamp; dist[u] = nd; prevv[u] = v; q[qt++] = u;
}
}
if (seen[s] != stamp) return {}; // Unreachable
vector<int> path;
path.reserve(dist[s] + 1);
for (int v = s; v != t; v = prevv[v]) path.push_back(v);
return path;
}
bool TryCreateCenterRoadLegacy() {
Init();
B[T] = B[T - 1] = B[T + 1] = B[T - C] = B[T + C] = 1;
int center = S;
int pat = rnd.next(15);
path.clear();
if (pat < 5) {
if (pat < 1) center += 1;
else if (pat < 2) center -= 1;
else center += C;
path.push_back(S);
} else if (pat < 7) {
int dy = rnd.next(0, 4);
int dx = rnd.next(-3, 4);
int d = dy + abs(dx);
if (d <= 1 || d >= 5) return false;
center = S + dy * C + dx;
if (B[center] > 0) return false;
path = ShortestPath(S, center);
for (int v : path) {
B[v] = B[v - 1] = B[v + 1] = B[v - C] = B[v + C] = 1;
}
B[center] = 0;
}
// TODO: Find a better center
int xl = (N + 1) / 2 - rnd.next(10);
// int xr = xl + rnd.next(2, 4);
int xr = (N + 3) / 2 + rnd.next(10);
int l1 = (N - rnd.next(2)) * C + xl;
int r1 = (N - rnd.next(2)) * C + xr;
int l2 = rnd.next(4, N - 6) * C + ((N - 3) / 2 - rnd.next(10));
// int l2 = (N - rnd.next(2)) * C + rnd.next(2);
int r2 = rnd.next(4, N - 6) * C + ((N + 7) / 2 + rnd.next(10));
int l3 = rnd.next(4, N - 6) * C + ((N - 7) / 2 - rnd.next(10));
// int l3 = rnd.next(4, N - 6) * C + rnd.next(2);
int r3 = rnd.next(4, N - 6) * C + ((N + 11) / 2 + rnd.next(10));
if (B[l1] > 0) return false;
if (B[r1] > 0) return false;
if (B[l2] > 0) return false;
if (B[r2] > 0) return false;
if (r1 - l1 == 1) return false;
if (rnd.next(2) == 0) {
std::swap(l1, r1);
std::swap(l2, r2);
std::swap(l3, r3);
}
// Left
vector<int> path1 = ShortestPath(center, l1);
if (path1.empty()) return false;
for (int v : path1) {
if (v == center || v == l1) continue;
B[v] = B[v - 1] = B[v + 1] = B[v - C] = B[v + C] = 1;
}
B[l1] = 0;
if (B[l2] > 0) return false;
vector<int> path1_2 = ShortestPath(l1, l2);
if (path1_2.empty()) return false;
for (int v : path1_2) {
if (v == l1 || v == l2) continue;
B[v] = B[v - 1] = B[v + 1] = B[v - C] = B[v + C] = 1;
}
path1.insert(path1.end(), path1_2.begin(), path1_2.end());
do {
B[l2] = 0;
if (B[l3] > 0) break;
vector<int> path1_3 = ShortestPath(l2, l3);
if (path1_3.empty()) break;
for (int v : path1_3) {
if (v == l2 || v == l3) continue;
B[v] = B[v - 1] = B[v + 1] = B[v - C] = B[v + C] = 1;
}
path1.insert(path1.end(), path1_3.begin(), path1_3.end());
} while (false);
// Right
B[center] = 0;
vector<int> path2 = ShortestPath(center, r1);
if (path2.empty()) return false;
for (int v : path2) {
if (v == center || v == r1) continue;
B[v] = B[v - 1] = B[v + 1] = B[v - C] = B[v + C] = 1;
}
B[r1] = 0;
if (B[r2] > 0) return false;
vector<int> path2_2 = ShortestPath(r1, r2);
if (path2_2.empty()) return false;
for (int v : path2_2) {
if (v == r1 || v == r2) continue;
B[v] = B[v - 1] = B[v + 1] = B[v - C] = B[v + C] = 1;
}
path2.insert(path2.end(), path2_2.begin(), path2_2.end());
do {
B[r2] = 0;
if (B[r3] > 0) break;
vector<int> path2_3 = ShortestPath(r2, r3);
if (path2_3.empty()) break;
for (int v : path2_3) {
if (v == r2 || v == r3) continue;
B[v] = B[v - 1] = B[v + 1] = B[v - C] = B[v + C] = 1;
}
path2.insert(path2.end(), path2_3.begin(), path2_3.end());
} while (false);
std::reverse(path1.begin(), path1.end());
path1.pop_back();
path.insert(path.begin(), path1.begin(), path1.end());
path.insert(path.end(), path2.begin(), path2.end());
sol_type = 1;
return true;
}
static inline bool FastDFS(const int dx[4][4], int start_v, int goal_x,
int8_t* B, std::vector<int>& path_buf) {
static int v_st[C * C];
static unsigned char ok_st[C * C];
static unsigned char dirrow_st[C * C];
static unsigned char child_st[C * C];
static unsigned char entered_st[C * C];
int sp = 0;
v_st[0] = start_v;
ok_st[0] = 0;
dirrow_st[0] = rnd.next(4);
child_st[0] = 0;
entered_st[0] = 0;
sp = 1;
path_buf.clear();
while (sp) {
int idx = sp - 1;
int v = v_st[idx];
unsigned char &ok = ok_st[idx];
unsigned char &dirrow = dirrow_st[idx];
unsigned char &child = child_st[idx];
unsigned char &entered = entered_st[idx];
if (!entered) {
if (ok >= 3 && (v % C) - 1 == goal_x) return true;
path_buf.push_back(v);
B[v]++; B[v - 1]++; B[v + 1]++; B[v - C]++; B[v + C]++;
entered = 1;
ok += (unsigned char)((v / C) - 1 >= N - 2);
}
bool advanced = false;
for (; child < 4; ++child) {
int u = v + dx[dirrow][child];
if (B[u] > 1) continue;
v_st[sp] = u;
ok_st[sp] = ok;
dirrow_st[sp] = rnd.next(4);
child_st[sp] = 0;
entered_st[sp] = 0;
++sp;
advanced = true;
break;
}
if (advanced) continue;
// B[v]--;
// B[v - 1]--; B[v + 1]--;
// B[v - C]--; B[v + C]--;
path_buf.pop_back();
--sp;
}
return false;
}
inline bool TryCreateCenterRoad() {
// if ( <= T % C - 1 && T % C - 1 <= N - N / 4 + 1) {
// return TryCreateCenterRoadLegacy();
// }
// if (rnd.next() % 100 < 50) return TryCreateCenterRoadLegacy();
// TODO: Revisit center
int center_y = rnd.next(1, 4);
int center_x = S % C - 5 + rnd.next(9);
int offset_x = rnd.next(6);
int goal_x = -1;
static vector<int> path_buf;
path_buf.clear();
// auto dfs = [&](auto&& self, const int dx[4][4], int v, int ok = 0) -> bool {
// if (ok >= 3 && v % C - 1 == goal_x) return true;
// path_buf.push_back(v);
// B[v]++; B[v - 1]++; B[v + 1]++; B[v - C]++; B[v + C]++;
// ok += v / C - 1 >= N - 2;
// // ok += v / C - 1 >= N - 1;
// int dir_type = rnd.next(4);
// REP(dir, 4) {
// int u = v + dx[dir_type][dir];
// if (B[u] > 1) continue;
// if (self(self, dx, u, ok)) return true;
// }
// // B[v]--; B[v - 1]--; B[v + 1]--; B[v - C]--; B[v + C]--;
// path_buf.pop_back();
// return false;
// };
// auto dfs2 = [&](auto&& self, const int dx[4][4], int v, int ok = 0) -> bool {
// if (ok == 0 && v / C - 1 == N - 1) ok = 1;
// if (ok == 1 && v / C - 1 == 1) ok = 2;
// if (ok == 2 && v % C - 1 == goal_x) return true;
// path_buf.push_back(v);
// B[v]++; B[v - 1]++; B[v + 1]++; B[v - C]++; B[v + C]++;
// int dir_type = rnd.next(4);
// REP(dir, 4) {
// int u = v + dx[dir_type][dir];
// if (B[u] > 1) continue;
// if (self(self, dx, u, ok)) return true;
// }
// // B[v - 1]--; B[v + 1]--; B[v - C]--; B[v + C]--;
// path_buf.pop_back();
// return false;
// };
auto do_left = [&](bool after) {
Init();
B[T] = B[T - 1] = B[T + 1] = B[T - C] = B[T + C] = 1;
goal_x = int(N * rnd.next(0.18, 0.25));
if (after) {
for (int v : path) {
auto embed = [&](int v) { if (v / C - 1 >= center_y) B[v] = 1; };
embed(v); embed(v - 1); embed(v + 1); embed(v - C); embed(v + C);
}
}
REP(i,N) REP(j,N) {
int v = (i + 1) * C + (j + 1);
if (j > max(center_x, S % C - 1)) B[v] = 1;
if (!after && j >= center_x && i >= center_y) {
if ((i + offset_x) % 6 < 3) continue;
B[v] = 1;
}
if (j < goal_x) B[v] = 1;
}
static constexpr int DX_LEFT[4][4] = {
{-C, 1, -1, C},
{-C, 1, C, -1},
{ 1, -C, -1, C},
{ 1, -C, C, -1},
};
if (!FastDFS(DX_LEFT, S, goal_x, B, path_buf)) return false;
return true;
};
auto do_right = [&](bool after) {
Init();
B[T] = B[T - 1] = B[T + 1] = B[T - C] = B[T + C] = 1;
goal_x = int(N * rnd.next(0.75, 0.82));
if (after) {
for (int v : path) {
auto embed = [&](int v) { if (v / C - 1 >= center_y) B[v] = 1; };
embed(v); embed(v - 1); embed(v + 1); embed(v - C); embed(v + C);
}
}
REP(i,N) REP(j,N) {
int v = (i + 1) * C + (j + 1);
if (j < min(center_x, S % C - 1)) B[v] = 1;
if (!after && j <= center_x && i >= center_y) {
if ((i + offset_x) % 6 < 3) continue;
B[v] = 1;
}
if (j > goal_x) B[v] = 1;
}
static constexpr int DX_RIGHT[4][4] = {
{-C, -1, 1, C},
{-C, -1, C, 1},
{-1, -C, 1, C},
{-1, -C, C, 1},
};
if (!FastDFS(DX_RIGHT, S, goal_x, B, path_buf)) return false;
return true;
};
bool left_first = rnd.next(2);
if (left_first) {
if (!do_left(false)) return false;
} else {
if (!do_right(false)) return false;
}
path = path_buf;
reverse(path.begin(), path.end());
path.pop_back();
path_buf.clear();
if (left_first) {
if (!do_right(true)) return false;
} else {
if (!do_left(true)) return false;
}
path.insert(path.end(), path_buf.begin(), path_buf.end());
if (!TryCreateCenterWall()) return false;
// Dump();
sol_type = 2;
return true;
}
bool TryCreateCenterWall() {
int n = path.size();
Init();
for (int i = 1; i + 1 < n; i++) {
int v = path[i];
B[v] = B[v - 1] = B[v + 1] = B[v - C] = B[v + C] = 1;
}
for (int i = 0; i < n; i++) {
int v = path[i];
B[v] = 0;
}
return true;
}
inline int ReachSize() const {
if (++GDIST_EPOCH == 0) {
memset(GDIST_S, 0, sizeof(GDIST_S));
GDIST_EPOCH = 1;
}
const uint32_t CUR = uint32_t(GDIST_EPOCH) << 16;
alignas(64) static int q[C * C];
int qh = 0, qt = 0;
q[qt++] = S;
if (B[S]) return 0;
GDIST_S[S] = CUR | 0u;
int cnt = 1;
int reach_T = 0;
while (qh < qt) {
const int v = q[qh++];
if (v == T) reach_T = 1;
const uint16_t nd = (uint16_t)((GDIST_S[v] & 0xFFFFu) + 1u);
int u = v + 1;
if (!B[u] && (GDIST_S[u] >> 16) != GDIST_EPOCH) {
GDIST_S[u] = CUR | nd; q[qt++] = u; ++cnt;
}
u = v - 1;
if (!B[u] && (GDIST_S[u] >> 16) != GDIST_EPOCH) {
GDIST_S[u] = CUR | nd; q[qt++] = u; ++cnt;
}
u = v + C;
if (!B[u] && (GDIST_S[u] >> 16) != GDIST_EPOCH) {
GDIST_S[u] = CUR | nd; q[qt++] = u; ++cnt;
}
u = v - C;
if (!B[u] && (GDIST_S[u] >> 16) != GDIST_EPOCH) {
GDIST_S[u] = CUR | nd; q[qt++] = u; ++cnt;
}
}
return reach_T ? cnt : 0;
}
double Eval1() const {
int cnt = ReachSize();
if (cnt == 0) return 0;
int path_size = path.empty() ? 0 : ShortestPath(path.front(), path.back()).size();
// int path_size = path.size();
// return (cnt - path_size * 0.8) * pow(path_size, 0.8);
return (cnt - path_size * 0.8) * pow(path_size, 0.9);
// return path_size;
}
int Eval2() const {
int cnt = ReachSize();
if (cnt == 0) return 0;
int path_size = path.empty() ? 0 : ShortestPath(path.front(), path.back()).size();
// return (n_plot + cnt * 0.01) * pow(path_size, 1.0);
return path_size;
}
double CreateCenterSnake() {
constexpr int n_try = 200;
int i_try = 0;
for (i_try = 0; i_try < n_try; i_try++) {
if (!TryCreateCenterRoad()) {
if (i_try < 1) continue;
if (!TryCreateCenterRoadLegacy()) continue;
}
if (!TryCreateCenterWall()) continue;
double res = Eval1();
// if (res <= 0) {
// if (B[T - C] + B[T - 1] + B[T + 1] + B[T + C] == 4) {
// if (Ti >= 1 && A[Ti-1][Tj] == 0 &&
// B[T - 2 * C] == 1 && B[T - C - 1] + B[T - C + 1] == 1) {
// B[T - C] = 0;
// res = Eval1();
// } else if (Tj >= 1 && A[Ti][Tj-1] == 0 &&
// B[T - 2] == 1 && B[T - 1 - C] + B[T - 1 + C] == 1) {
// B[T - 1] = 0;
// res = Eval1();
// } else if (Ti <= N - 2 && A[Ti+1][Tj] == 0 &&
// B[T + 2 * C] == 1 && B[T + C - 1] + B[T + C + 1] == 1) {
// B[T + C] = 0;
// res = Eval1();
// } else if (Tj <= N - 2 && A[Ti][Tj+1] == 0 &&
// B[T + 2] == 1 && B[T + 1 - C] + B[T + 1 + C] == 1) {
// B[T + 1] = 0;
// res = Eval1();
// }
// }
// }
if (res > 0) {
// LOG(i_try);
return res;
}
}
// LOG(i_try);
return 0;
}
inline void swap_with(int index, int8_t& value) {
// if (0 <= index && index < C * C)
std::swap(B[index], value);
}
// void SidePlot() {
// if (sol_type != 2) return;
// sol_type = 3;
// int x = T % C - 1;
// if (x >= 4) {
// int offset = rnd.next(5);
// REP(i,N) {
// int row = (i + offset) % 5;
// REP(j,2) {
// int v = (i + 1) * C + (j + 1);
// if (row == 0 || row == 1 || (row == 3 && j == 0)) {
// B[v] = 1;
// }
// }
// }
// }
// if (x < N - 5) {
// int offset = rnd.next(5);
// REP(i,N) {
// int row = (i + offset) % 5;
// REP(j,2) {
// int v = (i + 1) * C + (N - j);
// if (row == 0 || row == 1 || (row == 3 && j == 0)) {
// B[v] = 1;
// }
// }
// }
// }
// }
bool AroundPlot() {
static mt19937 rng;
static vector<vector<int>> plots = {
{T + 2, T - 1, T - C, T + C, T + 1 + C},
{T + 2, T - 1, T - C, T + C, T + 1 - C},
{T - 2, T + 1, T - C, T + C, T - 1 + C},
{T - 2, T + 1, T - C, T + C, T - 1 - C},
{T + 2 * C, T - C, T - 1, T + 1, T + C - 1},
{T + 2 * C, T - C, T - 1, T + 1, T + C + 1},
{T - 2 * C, T + C, T - 1, T + 1, T - C - 1},
{T - 2 * C, T + C, T - 1, T + 1, T - C + 1},
};
shuffle(ALL(plots), rng);
int8_t oldB[5] = {1, 1, 1, 1, 1};
// auto bestB = B;
int best_score = 0;
int best_index = -1;
REP(index, 8) {
const vector<int>& plot = plots[index];
if (plot[0] < 0 || plot[0] >= C * C) continue;
REP(i,5) swap_with(plot[i], oldB[i]);
int score = ShortestPath(S, T).size();
if (score > best_score) {
best_score = score;
best_index = index;
}
REP(i,5) swap_with(plot[i], oldB[i]);
}
// B = bestB;
if (best_index >= 0) {
REP(i,5) swap_with(plots[best_index][i], oldB[i]);
}
return best_score > 0;
}
inline bool maybe_split(int index) const {
static constexpr int dx[8] = {1, C + 1, C, C - 1, -1, -C - 1, -C, -C + 1};
if (0 <= index && index < C * C && B[index] == 0) {
int count = 0;
REP(i,8) {
int u1 = index + dx[i];
int u2 = index + dx[(i + 1) & 7];
count += (B[u1] ^ B[u2]);
}
return count >= 4;
}
return false;
}
int PostPlot() {
static mt19937 rng;
static vector<int> order;
static vector<int8_t> ploted(C * C, 0);
std::fill(ALL(ploted), 0);
for (int v : path) ploted[v] = 1;
ploted[S] = ploted[T] = 1;
if (order.empty()) {
REP(i,N) REP(j,N) order.push_back((i + 1) * C + (j + 1));
}
vector<vector<int>> dxs = {
{2, 1 + C, C, -1, -C, 1, -C + 1},
{2, 1 - C, -C, -1, C, 1, C + 1},
{-2, -1 + C, C, 1, -C, -1, -C - 1},
{-2, -1 - C, -C, 1, C, -1, C - 1},
{2 * C, C + 1, 1, -C, -1, C, C - 1},
{2 * C, C - 1, -1, -C, 1, C, C + 1},
{-2 * C, -C + 1, 1, C, -1, -C, -C - 1},
{-2 * C, -C - 1, -1, C, 1, -C, -C + 1},
};
n_plot = 0;
int reach_size = ReachSize();
REP(loop,2) {
shuffle(ALL(order), rng);
shuffle(ALL(dxs), rng);
for (int v : order) {
if (v == S || v == T || B[v] || ploted[v]) continue;
vector<int8_t> oldB = {1, 1, 1, 1, 1};
int best_score = 0;
int best_index = -1;
REP(index,dxs.size()) {
bool is_maybe_split = false;
const vector<int>& dx = dxs[index];
if (v + dx[0] < 0 || v + dx[0] >= C * C ||
B[v + dx[5]] || B[v + dx[6]]) continue;
bool has_plotted = false;
REP(i,7) {
int vi = v + dx[i];
if (ploted[vi]) has_plotted = true;
}
if (has_plotted) continue;
int count_zero = 0;
REP(i,5) {
int vi = v + dx[i];
is_maybe_split |= maybe_split(vi);
swap_with(vi, oldB[i]);
if (oldB[i] == 0) ++count_zero;
}
if (/* has_plotted || count_zero < 0 || */ count_zero > 2 + loop) {
REP(i,5) swap_with(v + dx[i], oldB[i]);
continue;
}
if (is_maybe_split) {
int reach_size_new = ReachSize();
if (reach_size_new + count_zero < reach_size) {
REP(i,5) swap_with(v + dx[i], oldB[i]);
continue;
}
}
int score = DistFromSIdx(v);
if (score > best_score) {
best_score = score;
best_index = index;
}
REP(i,5) swap_with(v + dx[i], oldB[i]);
}
if (best_index != -1) {
ploted[v] = 1;
n_plot++;
const vector<int>& dx = dxs[best_index];
int count_zero = 0;
REP(i,5) count_zero += (B[v + dx[i]] == 0);
REP(i,5) swap_with(v + dx[i], oldB[i]);
int p = v - dx[5] + dx[6] * 2;
if (0 <= p && B[p] == 0 && !ploted[p]) {
B[p] = 1;
int new_reach_size = ReachSize();
if (new_reach_size + count_zero + 1 >= reach_size) {
reach_size = new_reach_size;
continue;
}
B[p] = 0;
}
reach_size = ReachSize();
}
}
}
REP(loop,2) {
shuffle(ALL(order), rng);
for (int v : order) {
if (v == S || v == T || B[v] == 0 || A[v / C - 1][v % C - 1] == 1) continue;
int suma = 0, sumb = 0;
for (int d : {1, -1, C, -C}) {
suma += B[v + d] > 0;
if (B[v + d] == 0 && DistFromSIdx(v + d) == 0) sumb += 1;
}
if (suma == 2 && sumb == 1) {
B[v] = 0;
ReachSize();
}
}
}
return n_plot;
}
void PostPlotLegacy() {
constexpr int dx[8] = {C + 1, C, C - 1, -1, -C - 1, -C, -C + 1, 1};
auto count_around = [&](int v) {
int cnt = 0;
REP(d,8) {
int u = v + dx[d];
if (u / C == 0 || u / C == N + 1) continue;
if (u % C == 0 || u % C == N + 1) continue;
if (B[u] == 1) cnt++;
}
return cnt;
};
static mt19937 rng;
static vector<pair<int, int>> order;
if (order.empty()) { REP(i,N) REP(j,N) order.emplace_back(i, j); }
shuffle(ALL(order), rng);
for (auto [y, x] : order) {
// if (loop < 50000 && (y + x) % 2) continue;
int v = (y + 1) * C + (x + 1);
if (v == S || v == T || B[v]) continue;
if (count_around(v) == 0) B[v] = 1;
}
shuffle(ALL(order), rng);
for (auto [y, x] : order) {
int v = (y + 1) * C + (x + 1);
// if (loop < 50000 && (y + x) % 2) continue;
if (v == S || v == T || B[v] == 1) continue;
int cntd = 0, cnt = 0;
REP(d,8) {
int u1 = v + dx[d], u2 = v + dx[(d + 1) % 8];
cnt += B[u1];
if (B[u1] != B[u2]) cntd++;
}
if (cntd <= 2 && cnt <= 4) B[v] = 1; // TODO: Param
}
// REP(i,N) REP(j,N) {
// int v = (i + 1) * C + (j + 1);
// if (A[i][j] == 1 || B[v] == 0) continue;
// if (B[v - C] + B[v + C] + B[v - 1] + B[v + 1] >= 3) B[v] = 0;
// }
}
void Dump() const {
vector<string> grid(N + 2, string(N + 2, '#'));
REP(i,N) REP(j,N) {
if (A[i][j]) continue;
if (B[(i+1)*C+j+1]) {
grid[i+1][j+1] = '%';
} else {
grid[i+1][j+1] = '.';
}
}
grid[S / C][S % C] = 'S';
grid[T / C][T % C] = 'T';
REP(i,N+2) CERR() << grid[i] << "\n";
}
};
enum CellT {
kEmpty,
kBlock,
kUnkwon,
};
struct Runner {
vector<int> first_turn;
void Init(const int8_t* B) {
REP(i,N) REP(j,N) {
int v = (i + 1) * C + (j + 1);
assert (!(A[i][j] == 1 && B[v] == 0));
if (A[i][j] == 0 && B[v] == 1) {
first_turn.push_back(v);
}
}
}
void Run() {
cout << first_turn.size();
for (int v : first_turn) {
cout << " " << (v / C - 1) << " " << (v % C - 1);
}
cout << endl;
cout << -1 << endl;
return;
constexpr int MAX_TURNS = 100000;
REP(loop, MAX_TURNS) {
int pi, pj, n;
cin >> pi >> pj >> n;
REP(i,n) {
int x, y;
cin >> x >> y;
}
if (pi == Ti && pj == Tj) return;
if (loop == 0) {
cout << first_turn.size();
for (int v : first_turn) {
cout << " " << (v / C - 1) << " " << (v % C - 1);
}
cout << endl;
} else {
cout << 0 << endl;
}
}
}
};
struct Simulator {
alignas(64) int8_t B[C * C];
alignas(64) uint8_t R[C * C];
alignas(64) uint8_t BR[C * C];
alignas(64) uint16_t dist[C * C];
alignas(64) uint16_t dist_t[C * C];
alignas(64) uint8_t visited[C * C];
alignas(64) uint8_t revealed[C * C];
alignas(64) uint8_t vert[C * C];
alignas(64) uint8_t horiz[C * C];
alignas(64) int que[C * C];
bool dist_valid = false;
inline void RevealFrom(int v) {
if (revealed[v]) return;
bool no = true;
revealed[v] = true;
if (!vert[v]) {
// Up
int u = v;
do {
vert[u] = 1;
R[u] = 1;
u -= C;
} while (B[u] == 0);
if (no) {
no &= dist[v - C] >= dist[v];
dist_valid &= no || R[u] || dist[u] + (v - u) / C > dist[v];
}
R[u] = 1;
BR[u] = 1;
// Down
u = v;
do {
vert[u] = 1;
R[u] = 1;
u += C;
} while (B[u] == 0);
if (no) {
no &= dist[v + C] >= dist[v];
dist_valid &= no || R[u] || dist[u] + (u - v) / C > dist[v];
}
R[u] = 1;
BR[u] = 1;
}
if (!horiz[v]) {
// Left
int u = v;
do {
horiz[u] = 1;
R[u] = 1;
u -= 1;
} while (B[u] == 0);
if (no) {
no &= dist[v - 1] >= dist[v];
dist_valid &= no || R[u] || dist[u] + (v - u) > dist[v];
}
R[u] = 1;
BR[u] = 1;
// Right
u = v;
do {
horiz[u] = 1;
R[u] = 1;
u += 1;
} while (B[u] == 0);
if (no) {
no &= dist[v + 1] >= dist[v];
dist_valid &= no || R[u] || dist[u] + (u - v) > dist[v];
}
R[u] = 1;
BR[u] = 1;
}
}
int NextStep(int s, int t) {
if (!dist_valid) {
dist_valid = true;
std::fill(dist, dist + C * C, 30000);
dist[t] = 0;
int qh = 0, qt = 0;
que[qt++] = t;
while (qh < qt) {
int v = que[qh++];
if (v == s) break;
int d = dist[v] + 1;
int u = v - C; // Up
if (dist[u] > d && BR[u] == 0) { dist[u] = d; que[qt++] = u; }
u = v + C; // Down
if (dist[u] > d && BR[u] == 0) { dist[u] = d; que[qt++] = u; }
u = v - 1; // Left
if (dist[u] > d && BR[u] == 0) { dist[u] = d; que[qt++] = u; }
u = v + 1; // Right
if (dist[u] > d && BR[u] == 0) { dist[u] = d; que[qt++] = u; }
}
}
if (dist[s - C] < dist[s]) return s - C; // Up
if (dist[s + C] < dist[s]) return s + C; // Down
if (dist[s - 1] < dist[s]) return s - 1; // Left
if (dist[s + 1] < dist[s]) return s + 1; // Right
return -1;
}
Simulator(int8_t* B_) {
std::copy(B_, B_ + C * C, B);
std::fill(R, R + C * C, 1);
std::fill(BR, BR + C * C, 1);
std::fill(dist_t, dist_t + C * C, 30000);
dist_t[T] = 0;
int qh = 0, qt = 0;
que[qt++] = T;
while (qh < qt) {
int v = que[qh++];
int d = dist_t[v] + 1;
int u = v - C; // Up
if (dist_t[u] > d && B[u] == 0) { dist_t[u] = d; que[qt++] = u; }
u = v + C; // Down
if (dist_t[u] > d && B[u] == 0) { dist_t[u] = d; que[qt++] = u; }
u = v - 1; // Left
if (dist_t[u] > d && B[u] == 0) { dist_t[u] = d; que[qt++] = u; }
u = v + 1; // Right
if (dist_t[u] > d && B[u] == 0) { dist_t[u] = d; que[qt++] = u; }
}
}
inline int ReachCount() {
memset(visited, 0, sizeof(visited));
visited[S] = 1;
int qh = 0, qt = 0;
que[qt++] = S;
int count = 0;
while (qh < qt) {
int v = que[qh++];
int u = v - C; // Up
if (!visited[u] && BR[u] == 0)
{ visited[u] = 1; que[qt++] = u; count += (R[u] == 0); }
u = v + C; // Down
if (!visited[u] && BR[u] == 0)
{ visited[u] = 1; que[qt++] = u; count += (R[u] == 0); }
u = v - 1; // Left
if (!visited[u] && BR[u] == 0)
{ visited[u] = 1; que[qt++] = u; count += (R[u] == 0); }
u = v + 1; // Right
if (!visited[u] && BR[u] == 0)
{ visited[u] = 1; que[qt++] = u; count += (R[u] == 0); }
}
return count;
}
double Run(int seed) {
REP(i,N) REP(j,N) {
int v = (i+1)*C+j+1;
R[v] = 0;
BR[v] = 0;
}
memset(revealed, 0, sizeof(revealed));
memset(vert, 0, sizeof(vert));
memset(horiz, 0, sizeof(horiz));
mt19937 rng(seed);
vector<int> order;
order.reserve(N * N);
REP(i, N) REP(j, N) {
int v = (i + 1) * C + (j + 1);
// if (v == S || v == T) continue;
if (v == S) continue;
order.emplace_back(v);
}
shuffle(ALL(order), rng);
int pos = S;
int steps = 0;
int size = order.size();
RevealFrom(S);
REP(i,size) {
int v = order[i];
dist_valid = false;
if (R[v]) continue;
while (R[v] == 0) {
if (!timer.within()) return 0;
// assert (B[pos] == 0);
// assert (R[v] == 0);
int next_pos = NextStep(pos, v);
if (next_pos == -1) break; // Unreachable
// assert (B[next_pos] == 0);
if (R[T] == 1) {
assert(dist_t[pos] != 30000);
return steps;
// return steps + dist_t[pos];
}
// if (next_pos == -1) break;
pos = next_pos;
RevealFrom(pos);
++steps;
}
}
// return steps + dist_t[pos];
assert(dist_t[pos] != 30000);
return steps;
}
};
int main() {
SetUp();
int total_tries = 0;
vector<int> n_tries;
vector<double> sum_scores;
vector<double> sum2_scores;
vector<Simulator> simulators;
n_tries.reserve(1000);
sum_scores.reserve(1000);
sum2_scores.reserve(1000);
simulators.reserve(1000);
{
Board init_board;
init_board.Init();
// init_board.SidePlot();
init_board.AroundPlot();
init_board.PostPlot();
init_board.PostPlotLegacy();
simulators.emplace_back(init_board.B);
Simulator& simulator = simulators.back();
n_tries.push_back(0);
sum_scores.push_back(0);
sum2_scores.push_back(0);
REP(loop,2) {
double sim_score = simulator.Run(loop);
n_tries.back() += 1;
sum_scores.back() += sim_score;
sum2_scores.back() += sim_score * sim_score;
total_tries += 1;
}
}
int64_t until = timer.start + int64_t(TIME_LIMIT * 0.58 * Timer::CYCLES_PER_SEC);
int n_trial = 0;
bool exists_safe = false;
vector<Board> boards;
auto compare = [](auto &a, auto &b) { return get<1>(a) < get<1>(b); };
using T = tuple<int, double, int>;
priority_queue<T, vector<T>, decltype(compare)> que(compare);
for (;;) {
if (timer.get_cycle() > until && (int(n_tries.size()) >= 2 || !timer.within())) break;
constexpr int n_loop = 13;
REP(loop,n_loop) {
if (!timer.within()) break;
Board board;
double score = board.CreateCenterSnake();
if (score == 0) continue;
int ratio = -1;
// if (true || rnd.next(100) < 20) board.SidePlot();
if (!board.AroundPlot()) {
if (exists_safe) continue;
ratio = 1;
} else {
exists_safe = true;
ratio = 10;
}
que.emplace(boards.size(), score * ratio, ratio);
boards.push_back(board);
}
if (que.empty()) continue;
auto [board_index, _, ratio] = que.top();
que.pop();
Board& board = boards[board_index];
// REP(loop,1) {
// Board board2;
// board2.sol_type = board.sol_type;
// board2.path = board.path;
// std::copy(board.B, board.B + C * C, board2.B);
// board2.PostPlot();
// board2.PostPlotLegacy();
// int score = board2.Eval1() * ratio;
// if (score == 0) continue;
// n_trial++;
// cands.emplace_back(board2, score);
// }
board.PostPlot();
board.PostPlotLegacy();
double score = board.Eval1() * ratio;
// double score = board.Eval2() * ratio;
if (score == 0) continue;
n_trial++;
// LOG(score);
simulators.emplace_back(board.B);
Simulator& simulator = simulators.back();
n_tries.push_back(0);
sum_scores.push_back(0);
sum2_scores.push_back(0);
// warm up
REP(loop,4) {
double sim_score = simulator.Run(loop);
n_tries.back() += 1;
sum_scores.back() += sim_score;
sum2_scores.back() += sim_score * sim_score;
total_tries += 1;
}
}
LOG(simulators.size());
// UCB-V
const int n = (int)simulators.size();
int best_index = 0;
while (timer.within()) {
int best_i = -1;
double best_ucb = -1e300;
const double logT = std::log(std::max(2, total_tries)); // Avoid log(0)
REP(i,n) {
const int ni = n_tries[i];
if (ni == 0) { best_i = i; break; }
if (i == best_index) continue; // Don't select the current best
const double avg = sum_scores[i] / ni;
double var = sum2_scores[i] / ni - avg * avg;
if (var < 0) var = 0; // Numerical stability
// UCB-V index
const double bonus =
std::sqrt((2.0 * var * logT) / ni) + (3.0 * logT) / ni;
const double ucb = avg + bonus;
if (ucb > best_ucb) {
best_ucb = ucb;
best_i = i;
}
}
assert(best_i != -1);
double sim_score = simulators[best_i].Run(n_tries[best_i]);
n_tries[best_i] += 1;
sum_scores[best_i] += sim_score;
sum2_scores[best_i] += sim_score * sim_score;
total_tries += 1;
if (n_tries[best_i] > n_tries[best_index]) {
best_index = best_i;
}
}
// REP(i,n) CERR() << i << " " << n_tries[i] << " " << sum_scores[i] / max(1, n_tries[i]) << endl;
int max_tries = *max_element(ALL(n_tries));
LOG(max_tries);
LOG(total_tries);
vector<int> order(n);
iota(ALL(order), 0);
sort(ALL(order), [&](int i, int j) { return n_tries[i] > n_tries[j]; });
const int n_cands = std::max(2, int(sqrt(simulators.size())));
order.resize(n_cands);
sort(ALL(order), [&](int i, int j) {
return sum_scores[i] / max(1, n_tries[i]) > sum_scores[j] / max(1, n_tries[j]);
});
const int8_t* best_board = simulators[order[0]].B;
// // UCB1-Tuned
// vector<int> n_tries(cands.size(), 0);
// vector<double> sum_scores(cands.size(), 0);
// vector<double> sum2_scores(cands.size(), 0);
// int total_tries = 0;
// const int n = cands.size();
// int best_index = 0;
// vector<Simulator> simulators;
// simulators.reserve(n);
// REP(i,n) simulators.emplace_back(cands[i].first.B);
// while (timer.within()) {
// int best_i = -1;
// double best_ucb = -1;
// REP(i,n) {
// if (n_tries[i] < 2) {
// best_i = i;
// break;
// }
// if (best_index == i) continue;
// double avg = sum_scores[i] / n_tries[i];
// double var = sum2_scores[i] / n_tries[i] - avg * avg;
// var = max(var, 0.0);
// double logT = log(total_tries);
// // double delta = sqrt(logT / n_tries[i] * min(0.25, var + sqrt(2 * logT / n_tries[i])));
// double delta = sqrt(logT / n_tries[i] * var + sqrt(1.5 * logT / n_tries[i]));
// double ucb = avg + delta;
// if (ucb > best_ucb) {
// best_ucb = ucb;
// best_i = i;
// }
// }
// assert(best_i != -1);
// // Simulator simulator(cands[best_i].first.B);
// double sim_score = simulators[best_i].Run(n_tries[best_i]);
// n_tries[best_i]++;
// sum_scores[best_i] += sim_score;
// sum2_scores[best_i] += sim_score * sim_score;
// total_tries++;
// if (n_tries[best_i] > n_tries[best_index]) best_index = best_i;
// }
// // REP(i,n) CERR() << i << " " << n_tries[i] << " " << sum_scores[i] / max(1, n_tries[i]) << endl;
// int max_tries = *max_element(ALL(n_tries));
// LOG(max_tries);
// LOG(total_tries);
// vector<int> order(n);
// iota(ALL(order), 0);
// sort(ALL(order), [&](int i, int j) { return n_tries[i] > n_tries[j]; });
// const int n_cands = std::max(2, int(sqrt(cands.size())));
// order.resize(n_cands);
// sort(ALL(order), [&](int i, int j) { return sum_scores[i] / max(1, n_tries[i]) > sum_scores[j] / max(1, n_tries[j]); });
// Board best_board = cands[order[0]].first;
// best_board.PostPlot();
LOG(n_trial);
// LOG(best_board.sol_type);
// best_board.Dump();
Runner runner;
runner.Init(best_board);
runner.Run();
double elapsed = timer.elapsed();
LOG(elapsed);
std::_Exit(0);
}
提出情報
| 提出日時 |
|
| 問題 |
A - Treant's Forest |
| ユーザ |
asi1024 |
| 言語 |
C++ 23 (gcc 12.2) |
| 得点 |
651596 |
| コード長 |
40981 Byte |
| 結果 |
AC |
| 実行時間 |
1992 ms |
| メモリ |
54388 KiB |
コンパイルエラー
Main.cpp: In function ‘int main()’:
Main.cpp:1300:7: warning: unused variable ‘max_tries’ [-Wunused-variable]
1300 | int max_tries = *max_element(ALL(n_tries));
| ^~~~~~~~~
Main.cpp:1381:10: warning: unused variable ‘elapsed’ [-Wunused-variable]
1381 | double elapsed = timer.elapsed();
| ^~~~~~~
ジャッジ結果
| セット名 |
test_ALL |
| 得点 / 配点 |
651596 / 100000000000 |
| 結果 |
|
| セット名 |
テストケース |
| test_ALL |
test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| test_0000.txt |
AC |
1992 ms |
33304 KiB |
| test_0001.txt |
AC |
1983 ms |
22708 KiB |
| test_0002.txt |
AC |
1982 ms |
10848 KiB |
| test_0003.txt |
AC |
1984 ms |
52888 KiB |
| test_0004.txt |
AC |
1983 ms |
19692 KiB |
| test_0005.txt |
AC |
1983 ms |
17388 KiB |
| test_0006.txt |
AC |
1983 ms |
29752 KiB |
| test_0007.txt |
AC |
1982 ms |
7596 KiB |
| test_0008.txt |
AC |
1983 ms |
17416 KiB |
| test_0009.txt |
AC |
1984 ms |
53416 KiB |
| test_0010.txt |
AC |
1983 ms |
21996 KiB |
| test_0011.txt |
AC |
1983 ms |
29112 KiB |
| test_0012.txt |
AC |
1982 ms |
4296 KiB |
| test_0013.txt |
AC |
1983 ms |
21912 KiB |
| test_0014.txt |
AC |
1983 ms |
13512 KiB |
| test_0015.txt |
AC |
1982 ms |
6204 KiB |
| test_0016.txt |
AC |
1983 ms |
30216 KiB |
| test_0017.txt |
AC |
1983 ms |
16584 KiB |
| test_0018.txt |
AC |
1983 ms |
13032 KiB |
| test_0019.txt |
AC |
1983 ms |
18052 KiB |
| test_0020.txt |
AC |
1982 ms |
11436 KiB |
| test_0021.txt |
AC |
1984 ms |
36336 KiB |
| test_0022.txt |
AC |
1982 ms |
8772 KiB |
| test_0023.txt |
AC |
1983 ms |
17744 KiB |
| test_0024.txt |
AC |
1984 ms |
36200 KiB |
| test_0025.txt |
AC |
1984 ms |
41220 KiB |
| test_0026.txt |
AC |
1982 ms |
8196 KiB |
| test_0027.txt |
AC |
1983 ms |
13980 KiB |
| test_0028.txt |
AC |
1983 ms |
21520 KiB |
| test_0029.txt |
AC |
1983 ms |
30960 KiB |
| test_0030.txt |
AC |
1983 ms |
20996 KiB |
| test_0031.txt |
AC |
1982 ms |
11780 KiB |
| test_0032.txt |
AC |
1982 ms |
10572 KiB |
| test_0033.txt |
AC |
1983 ms |
20568 KiB |
| test_0034.txt |
AC |
1984 ms |
52900 KiB |
| test_0035.txt |
AC |
1982 ms |
10964 KiB |
| test_0036.txt |
AC |
1984 ms |
36564 KiB |
| test_0037.txt |
AC |
1983 ms |
16972 KiB |
| test_0038.txt |
AC |
1983 ms |
30212 KiB |
| test_0039.txt |
AC |
1983 ms |
20464 KiB |
| test_0040.txt |
AC |
1983 ms |
17976 KiB |
| test_0041.txt |
AC |
1984 ms |
37988 KiB |
| test_0042.txt |
AC |
1984 ms |
35348 KiB |
| test_0043.txt |
AC |
1983 ms |
29720 KiB |
| test_0044.txt |
AC |
1983 ms |
12428 KiB |
| test_0045.txt |
AC |
1982 ms |
11724 KiB |
| test_0046.txt |
AC |
1982 ms |
7620 KiB |
| test_0047.txt |
AC |
1983 ms |
18016 KiB |
| test_0048.txt |
AC |
1983 ms |
13112 KiB |
| test_0049.txt |
AC |
1982 ms |
9784 KiB |
| test_0050.txt |
AC |
1983 ms |
15920 KiB |
| test_0051.txt |
AC |
1982 ms |
11128 KiB |
| test_0052.txt |
AC |
1983 ms |
29832 KiB |
| test_0053.txt |
AC |
1982 ms |
3536 KiB |
| test_0054.txt |
AC |
1983 ms |
18624 KiB |
| test_0055.txt |
AC |
1983 ms |
28424 KiB |
| test_0056.txt |
AC |
1984 ms |
52888 KiB |
| test_0057.txt |
AC |
1983 ms |
22184 KiB |
| test_0058.txt |
AC |
1983 ms |
29632 KiB |
| test_0059.txt |
AC |
1982 ms |
12324 KiB |
| test_0060.txt |
AC |
1983 ms |
17424 KiB |
| test_0061.txt |
AC |
1982 ms |
13284 KiB |
| test_0062.txt |
AC |
1982 ms |
12488 KiB |
| test_0063.txt |
AC |
1984 ms |
54388 KiB |
| test_0064.txt |
AC |
1983 ms |
18240 KiB |
| test_0065.txt |
AC |
1983 ms |
18096 KiB |
| test_0066.txt |
AC |
1982 ms |
7532 KiB |
| test_0067.txt |
AC |
1984 ms |
35772 KiB |
| test_0068.txt |
AC |
1983 ms |
16624 KiB |
| test_0069.txt |
AC |
1984 ms |
36964 KiB |
| test_0070.txt |
AC |
1983 ms |
16464 KiB |
| test_0071.txt |
AC |
1983 ms |
20160 KiB |
| test_0072.txt |
AC |
1983 ms |
17516 KiB |
| test_0073.txt |
AC |
1982 ms |
11304 KiB |
| test_0074.txt |
AC |
1983 ms |
29620 KiB |
| test_0075.txt |
AC |
1983 ms |
21800 KiB |
| test_0076.txt |
AC |
1982 ms |
12280 KiB |
| test_0077.txt |
AC |
1982 ms |
10624 KiB |
| test_0078.txt |
AC |
1983 ms |
20536 KiB |
| test_0079.txt |
AC |
1983 ms |
29780 KiB |
| test_0080.txt |
AC |
1983 ms |
20264 KiB |
| test_0081.txt |
AC |
1983 ms |
17056 KiB |
| test_0082.txt |
AC |
1982 ms |
7936 KiB |
| test_0083.txt |
AC |
1983 ms |
19584 KiB |
| test_0084.txt |
AC |
1982 ms |
6936 KiB |
| test_0085.txt |
AC |
1984 ms |
37196 KiB |
| test_0086.txt |
AC |
1983 ms |
29200 KiB |
| test_0087.txt |
AC |
1982 ms |
10388 KiB |
| test_0088.txt |
AC |
1982 ms |
10876 KiB |
| test_0089.txt |
AC |
1982 ms |
7212 KiB |
| test_0090.txt |
AC |
1984 ms |
53872 KiB |
| test_0091.txt |
AC |
1983 ms |
28916 KiB |
| test_0092.txt |
AC |
1983 ms |
28660 KiB |
| test_0093.txt |
AC |
1982 ms |
11328 KiB |
| test_0094.txt |
AC |
1983 ms |
29144 KiB |
| test_0095.txt |
AC |
1982 ms |
7392 KiB |
| test_0096.txt |
AC |
1983 ms |
17316 KiB |
| test_0097.txt |
AC |
1983 ms |
20196 KiB |
| test_0098.txt |
AC |
1983 ms |
28516 KiB |
| test_0099.txt |
AC |
1984 ms |
36216 KiB |