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
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
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