Submission #2087422
Source Code Expand
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < int(n); ++ (i))
#define REP3(i, m, n) for (int i = (m); (i) < int(n); ++ (i))
#define REP_R(i, n) for (int i = int(n) - 1; (i) >= 0; -- (i))
#define REP3R(i, m, n) for (int i = int(n) - 1; (i) >= int(m); -- (i))
#define ALL(x) begin(x), end(x)
#define dump(x) cerr << #x " = " << x << endl
#define unittest_name_helper(counter) unittest_ ## counter
#define unittest_name(counter) unittest_name_helper(counter)
#define unittest __attribute__((constructor)) void unittest_name(__COUNTER__) ()
using ll = long long;
using namespace std;
template <class T> using reversed_priority_queue = priority_queue<T, vector<T>, greater<T> >;
template <class T> inline void chmax(T & a, T const & b) { a = max(a, b); }
template <class T> inline void chmin(T & a, T const & b) { a = min(a, b); }
template <typename X, typename T> auto vectors(X x, T a) { return vector<T>(x, a); }
template <typename X, typename Y, typename Z, typename... Zs> auto vectors(X x, Y y, Z z, Zs... zs) { auto cont = vectors(y, z, zs...); return vector<decltype(cont)>(x, cont); }
template <typename T> ostream & operator << (ostream & out, vector<T> const & xs) { REP (i, int(xs.size()) - 1) out << xs[i] << ' '; if (not xs.empty()) out << xs.back(); return out; }
const char cmd[] = { 'U', 'D', 'R', 'L' };
const int dy[] = { -1, 1, 0, 0 };
const int dx[] = { 0, 0, 1, -1 };
constexpr int n = 100;
constexpr int k = 8;
constexpr int h = 50;
constexpr int w = 50;
constexpr int t = 2500;
bool is_on_field(int y, int x) { return 0 <= y and y < h and 0 <= x and x < w; }
struct state_t {
bitset<h * w> visited;
size_t hash_visited;
int y, x;
int score;
int index;
};
inline bool is_trapped(state_t const & a, array<array<char, w>, h> const & f) {
return f[a.y][a.x] == 'x';
}
bool is_trapped_if_move(int dir, state_t const & a, array<array<char, w>, h> const & f) {
int ny = a.y + dy[dir];
int nx = a.x + dx[dir];
return f[ny][nx] == 'x';
}
void exec_move(int dir, state_t & a, array<array<char, w>, h> const & f) {
if (is_trapped(a, f)) return;
int ny = a.y + dy[dir];
int nx = a.x + dx[dir];
if (f[ny][nx] != '#') {
a.y = ny;
a.x = nx;
if (f[ny][nx] == 'o' and not a.visited[ny * w + nx]) {
a.visited[ny * w + nx] = true;
a.hash_visited = hash<bitset<h * w> >()(a.visited);
a.score += 1;
}
}
}
template <typename T>
struct single_list {
T value;
shared_ptr<single_list<T> > next;
};
template <int m>
struct beam_state {
shared_ptr<array<state_t, m> > state;
size_t hash_state;
int score;
shared_ptr<single_list<int> > cmds;
};
template <int m, class RandomGenerator>
vector<int> generate_tour(array<array<array<char, w>, h>, m> const & f, array<int, m> initial_y, array<int, m> initial_x, RandomGenerator & gen) {
vector<beam_state<m> > cur, prv; {
beam_state<m> init = {};
init.state = make_shared<array<state_t, m> >();
init.score = 0;
init.hash_state = -1;
REP (i, m) {
(*init.state)[i].visited.reset();
(*init.state)[i].hash_visited = hash<bitset<h * w> >()((*init.state)[i].visited);
(*init.state)[i].y = initial_y[i];
(*init.state)[i].x = initial_x[i];
(*init.state)[i].score = 0;
}
init.cmds = nullptr;
cur.push_back(init);
}
REP (iteration, t) {
cur.swap(prv);
cur.clear();
for (auto a : prv) {
REP (dir, 4) {
bool is_trapped = false;
REP (i, m) {
if (is_trapped_if_move(dir, (*a.state)[i], f[i])) {
is_trapped = true;
break;
}
}
if (is_trapped) continue;
beam_state<m> b = {};
b.state = make_shared<array<state_t, m> >(*a.state);
REP (i, m) {
exec_move(dir, (*b.state)[i], f[i]);
b.score += (*b.state)[i].score;
b.hash_state ^= hash<size_t>()((*b.state)[i].hash_visited ^ ((*b.state)[i].y << 16) ^ (*b.state)[i].x);
}
b.cmds = make_shared<single_list<int> >((single_list<int>) { dir, a.cmds });
cur.emplace_back(b);
}
}
int size = min<int>(100, cur.size());
partial_sort(cur.begin(), cur.begin() + size, cur.end(), [&](beam_state<m> const & a, beam_state<m> const & b) {
return a.score > b.score;
});
cur.resize(size);
sort(ALL(cur), [&](beam_state<m> const & a, beam_state<m> const & b) {
return a.hash_state < b.hash_state;
});
cur.erase(unique(ALL(cur), [&](beam_state<m> const & a, beam_state<m> const & b) {
return a.hash_state == b.hash_state;
}), cur.end());
}
auto it = max_element(ALL(cur), [&](beam_state<m> const & a, beam_state<m> const & b) {
return a.score > b.score;
})->cmds;
vector<int> cmds;
while (it) {
cmds.push_back(it->value);
it = it->next;
}
reverse(ALL(cmds));
return cmds;
}
int main() {
chrono::high_resolution_clock::time_point clock_begin = chrono::high_resolution_clock::now();
// input
{ string s; getline(cin, s); }
vector<array<array<char, w>, h> > f(n);
vector<int> start_y(n);
vector<int> start_x(n);
REP (i, n) {
REP (y, h) REP (x, w) {
cin >> f[i][y][x];
if (f[i][y][x] == '@') {
start_y[i] = y;
start_x[i] = x;
}
}
}
// solve
int highscore = -1;
array<int, k> result_maps;
string result_commands;
default_random_engine gen;
for (int iteration = 0; ; ++ iteration) {
chrono::high_resolution_clock::time_point clock_end = chrono::high_resolution_clock::now();
if (chrono::duration_cast<chrono::milliseconds>(clock_end - clock_begin).count() >= 3500) break;
vector<int> dirs; {
constexpr int m = 8;
vector<int> selected;
while (selected.size() < m) {
int j = uniform_int_distribution<int>(0, n - 1)(gen);
if (not count(ALL(selected), j)) {
selected.push_back(j);
}
}
array<array<array<char, w>, h>, m> fs;
array<int, m> start_ys;
array<int, m> start_xs;
REP (i, m) {
fs[i] = f[selected[i]];
start_ys[i] = start_y[selected[i]];
start_xs[i] = start_x[selected[i]];
}
dirs = generate_tour<m>(fs, start_ys, start_xs, gen);
}
vector<state_t> state(n);
REP (i, n) {
state[i].visited.reset();
state[i].index = i;
state[i].y = start_y[i];
state[i].x = start_x[i];
state[i].score = 0;
}
string commands;
for (int dir : dirs) {
commands += cmd[dir];
REP (i, n) {
exec_move(dir, state[i], f[i]);
}
}
sort(ALL(state), [&](state_t const & a, state_t const & b) {
return a.score > b.score;
});
int score = 0;
REP (i, k) {
score += state[i].score;
}
if (highscore < score) {
highscore = score;
REP (i, k) {
result_maps[i] = state[i].index;
}
result_commands = commands;
}
}
// output
REP (i, k) {
if (i) cout << ' ';
cout << result_maps[i];
}
cout << endl;
cout << result_commands << endl;
return 0;
}
Submission Info
Submission Time |
|
Task |
A - ゲーム実況者Xの挑戦 |
User |
kimiyuki |
Language |
C++14 (GCC 5.4.1) |
Score |
292021 |
Code Size |
7831 Byte |
Status |
AC |
Exec Time |
3977 ms |
Memory |
9728 KB |
Judge Result
Set Name |
test_01 |
test_02 |
test_03 |
test_04 |
test_05 |
test_06 |
test_07 |
test_08 |
test_09 |
test_10 |
test_11 |
test_12 |
test_13 |
test_14 |
test_15 |
test_16 |
test_17 |
test_18 |
test_19 |
test_20 |
test_21 |
test_22 |
test_23 |
test_24 |
test_25 |
test_26 |
test_27 |
test_28 |
test_29 |
test_30 |
Score / Max Score |
9984 / 20000 |
9610 / 20000 |
9748 / 20000 |
9946 / 20000 |
9727 / 20000 |
9575 / 20000 |
9786 / 20000 |
9663 / 20000 |
9549 / 20000 |
9824 / 20000 |
9802 / 20000 |
9730 / 20000 |
9666 / 20000 |
9714 / 20000 |
9431 / 20000 |
9649 / 20000 |
9762 / 20000 |
9826 / 20000 |
9699 / 20000 |
9837 / 20000 |
9766 / 20000 |
9819 / 20000 |
9733 / 20000 |
9639 / 20000 |
9956 / 20000 |
9766 / 20000 |
9755 / 20000 |
9748 / 20000 |
9552 / 20000 |
9759 / 20000 |
Status |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Set Name |
Test Cases |
test_01 |
subtask_01_01.txt |
test_02 |
subtask_01_02.txt |
test_03 |
subtask_01_03.txt |
test_04 |
subtask_01_04.txt |
test_05 |
subtask_01_05.txt |
test_06 |
subtask_01_06.txt |
test_07 |
subtask_01_07.txt |
test_08 |
subtask_01_08.txt |
test_09 |
subtask_01_09.txt |
test_10 |
subtask_01_10.txt |
test_11 |
subtask_01_11.txt |
test_12 |
subtask_01_12.txt |
test_13 |
subtask_01_13.txt |
test_14 |
subtask_01_14.txt |
test_15 |
subtask_01_15.txt |
test_16 |
subtask_01_16.txt |
test_17 |
subtask_01_17.txt |
test_18 |
subtask_01_18.txt |
test_19 |
subtask_01_19.txt |
test_20 |
subtask_01_20.txt |
test_21 |
subtask_01_21.txt |
test_22 |
subtask_01_22.txt |
test_23 |
subtask_01_23.txt |
test_24 |
subtask_01_24.txt |
test_25 |
subtask_01_25.txt |
test_26 |
subtask_01_26.txt |
test_27 |
subtask_01_27.txt |
test_28 |
subtask_01_28.txt |
test_29 |
subtask_01_29.txt |
test_30 |
subtask_01_30.txt |
Case Name |
Status |
Exec Time |
Memory |
subtask_01_01.txt |
AC |
3815 ms |
2152 KB |
subtask_01_02.txt |
AC |
3818 ms |
2140 KB |
subtask_01_03.txt |
AC |
3844 ms |
2120 KB |
subtask_01_04.txt |
AC |
3965 ms |
6576 KB |
subtask_01_05.txt |
AC |
3794 ms |
2124 KB |
subtask_01_06.txt |
AC |
3970 ms |
7900 KB |
subtask_01_07.txt |
AC |
3822 ms |
2132 KB |
subtask_01_08.txt |
AC |
3830 ms |
2132 KB |
subtask_01_09.txt |
AC |
3786 ms |
2120 KB |
subtask_01_10.txt |
AC |
3841 ms |
2140 KB |
subtask_01_11.txt |
AC |
3977 ms |
7772 KB |
subtask_01_12.txt |
AC |
3813 ms |
2140 KB |
subtask_01_13.txt |
AC |
3594 ms |
2136 KB |
subtask_01_14.txt |
AC |
3826 ms |
2120 KB |
subtask_01_15.txt |
AC |
3806 ms |
2140 KB |
subtask_01_16.txt |
AC |
3592 ms |
9728 KB |
subtask_01_17.txt |
AC |
3756 ms |
2140 KB |
subtask_01_18.txt |
AC |
3772 ms |
2160 KB |
subtask_01_19.txt |
AC |
3848 ms |
2124 KB |
subtask_01_20.txt |
AC |
3711 ms |
2700 KB |
subtask_01_21.txt |
AC |
3666 ms |
2124 KB |
subtask_01_22.txt |
AC |
3834 ms |
2132 KB |
subtask_01_23.txt |
AC |
3668 ms |
2116 KB |
subtask_01_24.txt |
AC |
3825 ms |
2124 KB |
subtask_01_25.txt |
AC |
3539 ms |
4160 KB |
subtask_01_26.txt |
AC |
3840 ms |
2156 KB |
subtask_01_27.txt |
AC |
3835 ms |
2112 KB |
subtask_01_28.txt |
AC |
3849 ms |
2144 KB |
subtask_01_29.txt |
AC |
3848 ms |
2140 KB |
subtask_01_30.txt |
AC |
3812 ms |
2144 KB |