Submission #63336074


Source Code Expand

// bool TEST = true;
bool TEST = false;

using namespace std;
#include<bits/stdc++.h>
#include<fstream>
#include <iostream>
#include <cstdlib>
#include <dirent.h>
// #include <atcoder/all>

// using namespace atcoder;

#define rep(i,n) for(ll (i)=0;(i)<(ll)(n);i++)
#define rrep(i,n) for(ll (i)=(ll)(n)-1;(i)>=0;i--)
#define range(i,start,end,step) for(ll (i)=start;(i)<(ll)(end);(i)+=(step))
#define rrange(i,start,end,step) for(ll (i)=start;(i)>(ll)(end);(i)+=(step))

#define dump(x)  cerr << "Line " << __LINE__ << ": " <<  #x << " = " << (x) << "\n";
#define spa << " " <<
#define cma << "," <<
#define fi first
#define se second
#define all(a)  (a).begin(),(a).end()
#define allr(a)  (a).rbegin(),(a).rend()

using ld = long double;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
 
template<typename T> using V = vector<T>;
template<typename T> using VV = V<V<T>>;
template<typename T, typename T2> using P = pair<T, T2>;
template<typename T, typename T2> using M = map<T, T2>;
template<typename T> using S = set<T>;
template<typename T, typename T2> using UM = unordered_map<T, T2>;
template<typename T> using PQ = priority_queue<T, V<T>, greater<T>>;
template<typename T> using rPQ = priority_queue<T, V<T>, less<T>>;
template<class T>vector<T> make_vec(size_t a){return vector<T>(a);}
template<class T, class... Ts>auto make_vec(size_t a, Ts... ts){return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));}
template<class SS, class T> ostream& operator << (ostream& os, const pair<SS, T> v){os << "(" << v.first << ", " << v.second << ")"; return os;}
template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { for (auto &e : v) os << e << ' '; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<vector<T>> &v){ for(auto &e : v){os << e << "\n";} return os;}
// struct fast_ios { fast_ios(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
 
template <class T> void UNIQUE(vector<T> &x) {sort(all(x));x.erase(unique(all(x)), x.end());}
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
void fail() { cout << -1 << '\n'; exit(0); }
inline int popcount(const int x) { return __builtin_popcount(x); }
inline int popcount(const ll x) { return __builtin_popcountll(x); }
template<typename T> void debug(vector<vector<T>>&v){for(ll i=0;i<v.size();i++)
{cerr<<v[i][0];for(ll j=1;j<v[i].size();j++)cerr spa v[i][j];cerr<<"\n";}};
template<typename T> void debug(vector<T>&v){if(v.size()!=0)cerr<<v[0];
for(ll i=1;i<v.size();i++)cerr spa v[i];
cerr<<"\n";};
template<typename T> void debug(priority_queue<T>&v){V<T> vals; while(!v.empty()) {cerr << v.top() << " "; vals.push_back(v.top()); v.pop();} cerr<<"\n"; for(auto val: vals) v.push(val);}
template<typename T, typename T2> void debug(map<T,T2>&v){for(auto [k,v]: v) cerr << k spa v << "\n"; cerr<<"\n";}
template<typename T, typename T2> void debug(unordered_map<T,T2>&v){for(auto [k,v]: v) cerr << k spa v << "\n";cerr<<"\n";}
V<int> listrange(int n) {V<int> res(n); rep(i,n) res[i]=i; return res;}

template<typename T> P<T,T> divmod(T a, T b) {return make_pair(a/b, a%b);}


#define VISUALIZE // 提出時にはここをコメントアウトすること。そうしないとTLEする。

#ifdef VISUALIZE

bool VISUALIZE_FLAG = true;
std::ofstream sVisStream("VisCommands.txt");


// ビジュアライザ上で表示される時間を指定します
#define vis_time(t) sVisStream << "time = " << (t) << ";" << endl;
// ビジュアライザ上で常に表示されます
#define vis_always(t) vis_time(-1)

// リファレンス https://p5js.org/reference/
// Web上のエディタ https://editor.p5js.org/
#define vis_arc(x, y, w, h, start, stop) sVisStream << "arc( " << (x) << ", " << (y) << ", " << (w) << ", " << (h) << ", " << (start) << ", " << (stop) << ");" << endl;
#define vis_ellipse(x, y, w, h) sVisStream << "ellipse( " << (x) << ", " << (y) << ", " << (w) << ", " << (h) << ");" << endl;
#define vis_circle(x, y, d) sVisStream << "circle( " << (x) << ", " << (y) << ", " << (d) << ");" << endl;
#define vis_line(x1, y1, x2, y2) sVisStream << "line( " << (x1) << ", " << (y1) << ", " << (x2) << ", " << (y2) << ");" << endl;
#define vis_point(x, y) sVisStream << "point( " << (x) << ", " << (y) << ");" << endl;
#define vis_quad(x1, y1, x2, y2, x3, y3, x4, y4) sVisStream << "quad( " << (x1) << ", " << (y1) << ", " << (x2) << ", " << (y2) << ", " << (x3) << ", " << (y3) << ", " << (x4) << ", " << (y4) << ");" << endl;
#define vis_rect(x, y, w, h) sVisStream << "rect( " << (x) << ", " << (y) << ", " << (w) << ", " << (h) << ");" << endl;
#define vis_square(x, y, s) sVisStream << "square( " << (x) << ", " << (y) << ", " << (s) << ");" << endl;
#define vis_triangle(x1, y1, x2, y2, x3, y3) sVisStream << "triangle( " << (x1) << ", " << (y1) << ", " << (x2) << ", " << (y2) << ", " << (x3) << ", " << (y3) << ");" << endl;

#define vis_background(r, g, b) sVisStream << "background(" << (r) << ", " << (g) << ", " << (b) << ");" << endl;
#define vis_clear() sVisStream << "clear();" << endl;
#define vis_colorMode(mode, max1, max2, max3, maxA) sVisStream << "colorMode(" << (mode) << ", " << (max1) << ", " << (max2) << ", " << (max3) << ", " << (maxA) << ");" << endl;
#define vis_fill(r, g, b, a) sVisStream << "fill(" << (r) << ", " << (g) << ", " << (b) << ", " << (a) << ");" << endl;
#define vis_noFill() sVisStream << "noFill();" << endl;
#define vis_noStroke() sVisStream << "noStroke();" << endl;
#define vis_stroke(r, g, b, a) sVisStream << "stroke(" << (r) << ", " << (g) << ", " << (b) << ", " << (a) << ");" << endl;
#define vis_erase() sVisStream << "erase();" << endl;
#define vis_noErase() sVisStream << "noErase();" << endl;

#define vis_textAlign(alignX, alignY) sVisStream << "textAlign(" << (alignX) << ", " << (alignY) << ");" << endl;
#define vis_textLeading(leading) sVisStream << "textLeading(" << (leading) << ");" << endl;
#define vis_textSize(size) sVisStream << "textSize(" << (size) << ");" << endl;
#define vis_textStyle(style) sVisStream << "textStyle(" << (style) << ");" << endl;
#define vis_textWidth(text) sVisStream << "textWidth(" << (text) << ");" << endl;
#define vis_textAscent() sVisStream << "textAscent();" << endl;
#define vis_textDescent() sVisStream << "textDescent();" << endl;
#define vis_textWrap(wrap) sVisStream << "textWrap(" << (wrap) << ");" << endl;
#define vis_text(str, x, y) sVisStream << "text("               \
                                       << "\"" << (str) << "\"" \
                                       << ", " << (x) << ", " << (y) << ");" << endl;

#else //  VISUALIZE

bool VISUALIZE_FLAG = false;
#define vis_time(t)
#define vis_always(t)

#define vis_arc(x, y, w, h, start, stop)
#define vis_ellipse(x, y, w, h)
#define vis_circle(x, y, d)
#define vis_line(x1, y1, x2, y2)
#define vis_point(x, y)
#define vis_quad(x1, y1, x2, y2, x3, y3, x4, y4)
#define vis_rect(x, y, w, h)
#define vis_square(x, y, s)
#define vis_triangle(x1, y1, x2, y2, x3, y3)

#define vis_background(r, g, b)
#define vis_clear()
#define vis_colorMode(mode, max1, max2, max3, maxA)
#define vis_fill(r, g, b, a)
#define vis_noFill()
#define vis_noStroke()
#define vis_stroke(r, g, b, a)
#define vis_erase()
#define vis_noErase()

#define vis_textAlign(alignX, alignY)
#define vis_textLeading(leading)
#define vis_textSize(size)
#define vis_textStyle(style)
#define vis_textWidth(text)
#define vis_textAscent()
#define vis_textDescent()
#define vis_textWrap(wrap)
#define vis_text(str, x, y)

#endif // VISUALIZE
//----------- p5visualizerのマクロ(ここまで) -------------



const ll INF = (1ll<<62);
// const ld EPS   = 1e-10;
// const ld PI    = acos(-1.0);

static unsigned int xxx=123456789,yyy=362436069,zzz=521288629,www=88675123;
unsigned int randxor()
{
    unsigned int t;
    t=(xxx^(xxx<<11));xxx=yyy;yyy=zzz;zzz=www; return( www=(www^(www>>19))^(t^(t>>8)) );
}
int random_select(V<ll> &vals) {
    // vals の重みで [0, vals.size()) からサンプリング
    ll s = 0;
    for (auto v : vals) s += v;
    ll val = randxor()%s;
    rep(i, vals.size()) {val -= vals[i]; if (val<=0) return i;}
    return vals.size()-1;
}
V<double> TIME_LIST;
auto _START_TIME = chrono::system_clock::now();
double current_time() {
    return chrono::duration_cast<chrono::microseconds>(chrono::system_clock::now() - _START_TIME).count() * 1e-6;
}


// 焼きなましのひな型

const double T_START = 5000;
const double T_FINAL = 0;
const double T_RATE = T_FINAL / T_START;
const double TIME_LIMIT = 2.8;

inline double temp() {
    // 指数減衰
    return T_START * pow(T_RATE, (current_time() / TIME_LIMIT));
}

const int N = 20;  // 盤面サイズ
// int M;
const vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
const string dir_chars = "UDLR";

struct Position {
    int x, y;
    
    bool operator==(const Position& other) const {
        return x == other.x && y == other.y;
    }
    
    bool operator<(const Position& other) const {
        return x < other.x || (x == other.x && y < other.y);
    }
};

class State {
public:
    vector<string> board;
    Position player;
    map<char, Position> holes;
    int M; // 鉱石の種類数
    vector<string> moves;
    vector<vector<int>> good_pos;
    
    State(const vector<string>& initial_board, int m) : board(initial_board), M(m) {
        find_initial_positions();
    }

    void add_move(int action, int dir) {
        moves.emplace_back(to_string(action) + " " + dir_chars[dir]);
    }
    
    void print_moves() {
        for (const string& move : moves) {
            cout << move << endl;
        }
    }
    void find_initial_positions() {
        good_pos = vector<vector<int>>(N, vector<int>(N, 0));
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                char c = board[i][j];
                if (c == 'A') {
                    player = {i, j};
                } if (c >= 'A' && c <= 'Z') {
                    holes[c] = {i, j};
                    
                    // for(int k=c; k)

                }
            }
        }
    }

    bool is_valid_move(int x, int y) {
        return x >= 0 && x < N && y >= 0 && y < N;
    }

    bool move(int dir) {
        int nx = player.x + directions[dir].first;
        int ny = player.y + directions[dir].second;
        if (!is_valid_move(nx, ny)) return false;
        player = {nx, ny};
        add_move(1, dir);
        return true;
    }

    bool move_to(Position target) {
        while (player.x != target.x) {
            if (player.x < target.x) move(1); // 下へ移動
            else move(0); // 上へ移動
        }
        while (player.y != target.y) {
            if (player.y < target.y) move(3); // 右へ移動
            else move(2); // 左へ移動
        }
        return true;
    }


    bool push(int dir) {
        assert(is_pushable(player));

        int nx = player.x;
        int ny = player.y;
        if (!is_valid_move(nx, ny) || board[nx][ny] == '.') {
            cerr << "first" << endl;
            cerr << nx << " " << ny << " " << board[nx][ny] << endl;
            return false;
        }
        int tx = nx + directions[dir].first;
        int ty = ny + directions[dir].second;
        char tc = board[tx][ty];
        if (!is_valid_move(tx, ty) || (tc != '.' && !(tc <= 'Z' && tc >= 'A'))) {
            cerr << "second" << endl;
            return false;
        }
        
        cerr <<nx spa ny spa tx spa ty spa  board[nx][ny] spa tc << endl;
        if('A' <= tc && tc <= 'Z') {
            if(board[nx][ny] - 'a' != tc - 'A') {
                cerr << "!!push to another hole" << endl;
            }
            board[nx][ny] = '.';
        }
        else {
            swap(board[nx][ny], board[tx][ty]);
        }
        player = {tx, ty};
        add_move(2, dir);
        return true;
    }

    bool roll(int dir) {
        
        assert(is_pushable(player));
        int nx = player.x + directions[dir].first;
        int ny = player.y + directions[dir].second;
        cerr << "dir" << dir << endl;
        if (!is_valid_move(nx, ny) ) return false;
        
        while (is_valid_move(nx, ny) && board[nx][ny] == '.') {
            nx += directions[dir].first;
            ny += directions[dir].second;
        }
        if(is_valid_move(nx, ny) && board[nx][ny] >= 'A' && board[nx][ny] <= 'Z') {
            if(board[nx][ny] - 'A' != board[player.x][player.y] - 'a')
                cerr << "roll another" spa board[nx][ny] spa board[player.x][player.y] <<  endl;
            board[player.x][player.y] = '.';
        }
        else {
            cerr <<"to pre"<< nx << " " << ny << endl;
            nx -= directions[dir].first;
            ny -= directions[dir].second;
        
            if (!is_valid_move(nx, ny)) return false;
            cerr <<"to" <<  nx << " " << ny << endl;
            swap(board[nx][ny], board[player.x][player.y]);
        }
        add_move(3, dir);
        return true;
    }
    // queue の持ち方が雑...
    bool push_to(Position target) {
        cerr << "push to : " << target.x << " " << target.y << endl;
        if(board[target.x][target.y] == '@' || (board[target.x][target.y] >= 'a' && board[target.x][target.y] <= 'z'))
            return false;
        queue<pair<Position, vector<int>>> q;
        map<Position, bool> visited;
        q.push({player, {}});
        visited[player] = true;
        
        while (!q.empty()) {
            auto [pos, path] = q.front(); q.pop();
            if (pos == target) {
                for (int dir : path) {
                    cerr << dir << endl;
                    assert(push(dir));
                }
                return true;
            }
            
            for (int i = 0; i < 4; ++i) {
                int nx = pos.x + directions[i].first;
                int ny = pos.y + directions[i].second;
                if (is_valid_move(nx, ny) && !visited[{nx, ny}] && (board[nx][ny] == '.' || target == Position({nx, ny}))) {
                    visited[{nx, ny}] = true;
                    vector<int> new_path = path;
                    new_path.push_back(i);
                    q.push({{nx, ny}, new_path});
                }
            }
        }
        return false;
    }
    bool is_pushable(Position pos) {
        char c = board[pos.x][pos.y];
        if(c == '@') return true;
        if(c >= 'a' && c <= 'z') return true;
        return false;
    }
};

// class MoveSequence {
// public:
//     vector<string> moves;
    
//     void add_move(int action, int dir) {
//         moves.emplace_back(to_string(action) + " " + dir_chars[dir]);
//     }
    
//     void print_moves() {
//         for (const string& move : moves) {
//             cout << move << endl;
//         }
//     }
// };

class Game {
public:
    State *state;
    int M;

    Game(const vector<string>& board, int m) {
        state = new State(board, m);
        M = m;
    }


    // from->toへ向かうときのdirを取得する
    int get_dir(Position from, Position to) {

        if(to.x == from.x) {
            if(to.y < from.y) return  2;
            else if(to.y > from.y) return 3;
            else assert(false);
        }
        else if(to.y == from.y) {
            if(to.x < from.x) return  0;
            else if(to.x > from.x) return  1;
            else assert(false);
        }
        assert(false);
        return  -1;

    }
    // まっすぐのパスのposition を取得する
    vector<Position> get_positions (Position from, Position to){
        vector<Position> ret;
        if(from.x == to.x) {
            if(from.y < to.y) {
                for(int y=from.y+1; y<=to.y; y++)
                    ret.push_back({from.x, y});
            }
            else {
                for(int y=from.y-1; y>=to.y; y--)
                    ret.push_back({from.x, y});
            }
        }
        if(from.y == to.y) {
            if(from.x < to.x) {
                for(int x=from.x+1; x<=to.x; x++) {
                    ret.push_back({x, from.y});
                }
            }
            
            else {
                for(int x=from.x-1; x>=to.x; x--) {
                    ret.push_back({x, from.y});
                }
            }

        }
        
        return ret;

    }
    
    void solve() {
        // vector<vector<int>> dat;
        // 簡単なランダム解法(後で改善)
        // for (int i = 0; i < 100; ++i) {
        //     int action = rand() % 3 + 1;
        //     int dir = rand() % 4;
        //     if (action == 1 && state->move(dir)) {
        //         move_seq.add_move(1, dir);
        //     } else if (action == 2 && state->push(dir)) {
        //         move_seq.add_move(2, dir);
        //     } else if (action == 3 && state->roll(dir)) {
        //         move_seq.add_move(3, dir);
        //     }
        // }
        int blocker_cnt = 0;


        while(true) {
            // シンプルに残りの石を探す。
            int min_dist = 2 * N + 10;
            Position null_pos = {-1, -1};
            Position obj = null_pos;
            for(int i=0; i<N; i++) {
                for(int j=0; j<N; j++) {
                    if(state->board[i][j] >= 'a' && state->board[i][j] <= 'z') {

                        int d = abs(state->player.x - i) + abs(state->player.y - j);
                        if(min_dist > d ) {
                            min_dist = d;
                            obj = {i, j};
                        }
                    }
                }
            }
            if(obj == null_pos) break;

            state->move_to(obj);
            // いくつか択があるが、一旦適当に運ぶ
            
            char color = state->board[obj.x][obj.y] - 'a' + 'A';
            Position hole = state->holes[color];
            cerr << "hole;" <<  obj.x << " " << obj.y << " " << color <<  hole.x << " " << hole.y << endl;

            auto get_score = [&](Position mid){
                vector<Position> ps = get_positions(hole, mid);
                vector<Position> ps2 = get_positions(mid, obj);

                int score = 0;
                for(auto pos: ps) {
                    char c = state->board[pos.x][pos.y];
                    if(c == '@')score += 1;
                    if(c >= 'a' && c <= 'z') score += 1;
                    if(c >= 'A' && c <= 'Z') score += 100; 
                }

                for(auto pos: ps2) {
                    char c = state->board[pos.x][pos.y];
                    if(c == '@') score += 1;
                    if(c >= 'a' && c <= 'z') score += 1;
                    if(c >= 'A' && c <= 'Z') score += 10;
                    if(c == '.') score += 1;
                }
                return score;
                
            };
            
            Position mid = obj;
            if(hole.x != obj.x && hole.y != obj.y) {
                Position mid1 = {hole.x, obj.y};
                Position mid2 = {obj.x, hole.y};

                
                int scoreA = get_score(mid1);
                int scoreB = get_score(mid2);
                if(scoreA < scoreB) {
                    mid = {hole.x, obj.y};
                    
                }
                else {
                    mid = {obj.x, hole.y};
                }
                char midc = state->board[mid.x][mid.y];
                if(midc >= 'A' && midc <= 'Z') {
                    if(!state->push_to(hole)) {
                        cerr << "!!!WARNING" << endl;
                    }
                    continue;
                }
                if(!state->push_to(mid)){
                    if(!state->push_to(hole)) {
                        char c = state->board[mid.x][mid.y];
                        if(c != '.' && !(c >= 'A' && c <= 'Z')) {
                            // mid で続行
                            state->move_to(mid);
                            cerr << "continue!" << endl;
                        }
                        // それ以外。経路上のものを強制的に移動させる。
                        else {

                            // state->move_to(hole);
                            
                            int dir = get_dir(mid, hole);

                            
                            vector<Position> ps = get_positions(hole, mid);
                            vector<Position> ps2 = get_positions(mid, obj);
                            // for(auto x: ps2) ps.push_back(x); 

                            // assert(ps.size() == 0);
                            
                            if(M == 1) {
                                for(auto pos: ps){
                                    if(!state->is_pushable(pos)) continue;
                                    cerr << "!!!!" << pos.x << " " << pos.y << endl;
                                    
                                    state->move_to(pos);
                                    state->roll(dir);
                                }
                                dir = get_dir(obj, mid);
                                for(auto pos: ps2) {
                                    if(!state->is_pushable(pos)) continue;
                                    if(pos == obj) continue;

                                    cerr << "!!!!" << pos.x << " " << pos.y << endl;
                                    state->move_to(pos);
                                    state->roll(dir);
                                }

                            }
                            else {
                                bool moved = false;
                                for(auto pos: ps){
                                    if(!state->is_pushable(pos)) continue;
                                    state->move_to(pos);
                                    moved = true;
                                    break;
                                }
                                if(!moved)for(auto pos: ps2) {
                                    if(!state->is_pushable(pos)) continue;
                                    if(pos == obj) continue;
                                    state->move_to(pos);
                                    moved = true;
                                    break;
                                }
                                assert(moved);
                                continue;


                            }
                            // はじめからやり直す
                            continue;

                        }

                        

                    }
                    else {
                        continue;
                    }
                }
            }


            // bool is_moved = false;
            bool have_other_hole = false;
            Position blocker = null_pos;
            if(hole.x == mid.x) {
                if(hole.y < mid.y) {
                    for(int y=hole.y+1; y < mid.y; y++) {
                        char c = state->board[hole.x][y];
                        if(c >= 'A' &&  c < 'Z') 
                            have_other_hole = true;
                        if(state->is_pushable({hole.x, y}) && blocker == null_pos) blocker = {hole.x, y};
                    }
                }
                if(hole.y > mid.y) {
                    for(int y = mid.y + 1; y < hole.y; y++) {
                        char c = state->board[hole.x][y];
                        if(c >= 'A' &&  c < 'Z') 
                            have_other_hole = true;
                        if(state->is_pushable({hole.x, y})) blocker = {hole.x, y};

                    }

                }
            }
            if(hole.y == mid.y) {
                if(hole.x < mid.x) {
                    for(int x=hole.x+1; x < mid.x; x++) {
                        char c = state->board[x][hole.y];
                        if(c >= 'A' &&  c < 'Z') 
                            have_other_hole = true;
                        if(state->is_pushable({x, hole.y}) && blocker == null_pos) blocker = {x, hole.y};

                    }
                }
                if(hole.x > mid.x) {
                    for(int x = mid.x + 1; x < hole.x; x++) {
                        char c = state->board[x][hole.y];
                        if(c >= 'A' &&  c < 'Z') 
                            have_other_hole = true;
                        if(state->is_pushable({x, hole.y})) blocker = {x, hole.y};

                    }
                }
            }
            if(have_other_hole) {
                state->push_to(hole);
                continue;
            }

            if(!(blocker == null_pos)) {
                mid = blocker; // 中間点を書き換え、岩を落とす。
                state->move_to(mid);
                cerr << "move to blocker" << endl;
                blocker_cnt++;
                if(blocker_cnt < 2) {
                    continue;
                }
                blocker_cnt = 0;
                char c = state->board[blocker.x][blocker.y]; 
                if(c >= 'a' && c <= 'c') {

                    if(state->push_to(state->holes[c - 'a' + 'A'])) {
                        continue;
                    }
                }
                state->roll(get_dir(mid, hole));
                continue;
            } 
            cerr << state->player.x << " " << state->player.y << " " <<  mid.x << " " << mid.y  << endl;
            
            state->roll(get_dir(mid, hole));
            // if(hole.x == mid.x) {
            //     if(hole.y < mid.y) state->roll(2);
            //     if(hole.y > mid.y) state->roll(3);
            // }
            // else if(hole.y == mid.y) {
            //     if(hole.x < mid.x) state->roll(0);
            //     if(hole.x > mid.x) state->roll(1);
            // }
            // else {
            //     assert(false);
            // }
            for(int i=0; i<N; i++)
                cerr << state->board[i] << endl;


        }

    }
    
    void print_solution() {
        state->print_moves();
    }
};



void Main() {

    int N, M;
    cin >> N >> M; // M : global
    vector<string> board(N);
    for (int i = 0; i < N; ++i) {
        cin >> board[i];
    }
    
    Position pos;
    for(int i=0; i<N; i++) for(int j=0; j<N; j++) {
        if(board[i][j] == 'A') pos = {i, j};
    }
    for(int i=0; i<N; i++) {
        if(board[i][pos.y] == '@') board[i][pos.y] = 'a';
        if(board[pos.x][i] == '@') board[pos.x][i] = 'a';
    }
    Game game(board, M);
    game.solve();
    game.print_solution();
    
    return;


}


V<string> search_dir(const char *path, int l, int l2){
    DIR *dp;
    dp = opendir(path);
    if (dp==NULL) exit(1);
    dirent* entry = readdir(dp);
    V<string> fs;
    while (entry != NULL){
        string s = string(path, l) + string(entry->d_name, l2);
        if (s[s.length()-1]=='t') {
            fs.push_back(s);
        }
        entry = readdir(dp);
    }
    return fs;
}
void Main_test(){
    V<string> fs = search_dir("./in/", 5, 8); // (ディレクトリ名長さ, ファイル名長さ)
    for (auto f : fs) {
        cout << f << endl;
        std::ifstream in(f);
        std::cin.rdbuf(in.rdbuf());
        _START_TIME = chrono::system_clock::now();
        std::cout << std::fixed << std::setprecision(15);
        Main();
        break;
    }
}


int main(void){
    std::cin.tie(nullptr);
	std::ios_base::sync_with_stdio(false);
    if (TEST) Main_test();
    else Main();
    return 0;
}

Submission Info

Submission Time
Task B - Ore Rolling (B)
User tokoharu
Language C++ 20 (gcc 12.2)
Score 730560991
Code Size 28517 Byte
Status AC
Exec Time 15 ms
Memory 3832 KiB

Compile Error

Main.cpp: In function ‘V<int> listrange(int)’:
Main.cpp:14:25: warning: unnecessary parentheses in declaration of ‘i’ [-Wparentheses]
   14 | #define rep(i,n) for(ll (i)=0;(i)<(ll)(n);i++)
      |                         ^~~
Main.cpp:63:41: note: in expansion of macro ‘rep’
   63 | V<int> listrange(int n) {V<int> res(n); rep(i,n) res[i]=i; return res;}
      |                                         ^~~
Main.cpp:14:25: note: remove parentheses
   14 | #define rep(i,n) for(ll (i)=0;(i)<(ll)(n);i++)
      |                         ^~~
Main.cpp:63:41: note: in expansion of macro ‘rep’
   63 | V<int> listrange(int n) {V<int> res(n); rep(i,n) res[i]=i; return res;}
      |                                         ^~~
Main.cpp: In function ‘int random_select(V<long long int>&)’:
Main.cpp:14:25: warning: unnecessary parentheses in declaration of ‘i’ [-Wparentheses]
   14 | #define rep(i,n) for(ll (i)=0;(i)<(ll)(n);i++)
      |                         ^~~
Main.cpp:171:5: note: in expansion of macro ‘rep’
  171 |     rep(i, vals.size()) {val -= vals[i]; if (val<=0) return i;}
      |     ^~~
Main.cpp:14:25: note: remove parentheses
   14 | #define rep(i,n) for(ll (i)=0;(i)<(ll)(n);i++)
      |                         ^~~
Main.cpp:171:5: note: in expansion of macro ‘rep’
  171 |     rep(i, vals.size()) {val -= vals[i]; if (val<=0) return i;}
      |     ^~~
Main.cpp: In function ‘void Main()’:
Main.cpp:728:23: warning: ‘pos.Position::x’ may be used uninitialized [-Wmaybe-uninitialized]
  728 |         if(board[pos.x][i] == '@') board[pos.x][i] = 'a';
      |                       ^
Main.cpp:722:14: note: ‘pos.Position::x’ was declared here
  722 |     Position pos;
      |              ^~~
Main.cpp:727:26: warning: ‘pos.Position::y’ may be used uninitialized [-Wmaybe-uninitialized]
  727 |         if(board[i][pos.y] == '@') board[i][pos.y] = 'a';
      |                          ^
Main.cpp:722:14: note: ‘pos.Position::y’ was declared here
  722 |     Position pos;
      |              ^~~

Judge Result

Set Name test_ALL
Score / Max Score 730560991 / 1500000000
Status
AC × 150
Set Name Test Cases
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_0100.txt, test_0101.txt, test_0102.txt, test_0103.txt, test_0104.txt, test_0105.txt, test_0106.txt, test_0107.txt, test_0108.txt, test_0109.txt, test_0110.txt, test_0111.txt, test_0112.txt, test_0113.txt, test_0114.txt, test_0115.txt, test_0116.txt, test_0117.txt, test_0118.txt, test_0119.txt, test_0120.txt, test_0121.txt, test_0122.txt, test_0123.txt, test_0124.txt, test_0125.txt, test_0126.txt, test_0127.txt, test_0128.txt, test_0129.txt, test_0130.txt, test_0131.txt, test_0132.txt, test_0133.txt, test_0134.txt, test_0135.txt, test_0136.txt, test_0137.txt, test_0138.txt, test_0139.txt, test_0140.txt, test_0141.txt, test_0142.txt, test_0143.txt, test_0144.txt, test_0145.txt, test_0146.txt, test_0147.txt, test_0148.txt, test_0149.txt
Case Name Status Exec Time Memory
test_0000.txt AC 11 ms 3692 KiB
test_0001.txt AC 13 ms 3704 KiB
test_0002.txt AC 10 ms 3752 KiB
test_0003.txt AC 14 ms 3704 KiB
test_0004.txt AC 13 ms 3708 KiB
test_0005.txt AC 12 ms 3712 KiB
test_0006.txt AC 13 ms 3720 KiB
test_0007.txt AC 9 ms 3688 KiB
test_0008.txt AC 9 ms 3680 KiB
test_0009.txt AC 9 ms 3680 KiB
test_0010.txt AC 11 ms 3568 KiB
test_0011.txt AC 10 ms 3564 KiB
test_0012.txt AC 10 ms 3624 KiB
test_0013.txt AC 10 ms 3744 KiB
test_0014.txt AC 12 ms 3692 KiB
test_0015.txt AC 12 ms 3828 KiB
test_0016.txt AC 12 ms 3660 KiB
test_0017.txt AC 11 ms 3700 KiB
test_0018.txt AC 11 ms 3748 KiB
test_0019.txt AC 11 ms 3708 KiB
test_0020.txt AC 10 ms 3764 KiB
test_0021.txt AC 12 ms 3716 KiB
test_0022.txt AC 9 ms 3692 KiB
test_0023.txt AC 9 ms 3696 KiB
test_0024.txt AC 11 ms 3832 KiB
test_0025.txt AC 12 ms 3712 KiB
test_0026.txt AC 11 ms 3696 KiB
test_0027.txt AC 10 ms 3688 KiB
test_0028.txt AC 10 ms 3824 KiB
test_0029.txt AC 10 ms 3756 KiB
test_0030.txt AC 12 ms 3704 KiB
test_0031.txt AC 10 ms 3684 KiB
test_0032.txt AC 10 ms 3692 KiB
test_0033.txt AC 10 ms 3692 KiB
test_0034.txt AC 10 ms 3692 KiB
test_0035.txt AC 11 ms 3780 KiB
test_0036.txt AC 11 ms 3632 KiB
test_0037.txt AC 11 ms 3708 KiB
test_0038.txt AC 11 ms 3708 KiB
test_0039.txt AC 10 ms 3632 KiB
test_0040.txt AC 10 ms 3696 KiB
test_0041.txt AC 11 ms 3696 KiB
test_0042.txt AC 9 ms 3760 KiB
test_0043.txt AC 10 ms 3772 KiB
test_0044.txt AC 12 ms 3776 KiB
test_0045.txt AC 11 ms 3756 KiB
test_0046.txt AC 11 ms 3756 KiB
test_0047.txt AC 14 ms 3700 KiB
test_0048.txt AC 10 ms 3676 KiB
test_0049.txt AC 10 ms 3696 KiB
test_0050.txt AC 12 ms 3756 KiB
test_0051.txt AC 12 ms 3760 KiB
test_0052.txt AC 12 ms 3704 KiB
test_0053.txt AC 11 ms 3564 KiB
test_0054.txt AC 11 ms 3704 KiB
test_0055.txt AC 10 ms 3652 KiB
test_0056.txt AC 11 ms 3752 KiB
test_0057.txt AC 11 ms 3676 KiB
test_0058.txt AC 11 ms 3696 KiB
test_0059.txt AC 10 ms 3828 KiB
test_0060.txt AC 13 ms 3632 KiB
test_0061.txt AC 10 ms 3648 KiB
test_0062.txt AC 11 ms 3768 KiB
test_0063.txt AC 11 ms 3696 KiB
test_0064.txt AC 10 ms 3668 KiB
test_0065.txt AC 11 ms 3696 KiB
test_0066.txt AC 10 ms 3824 KiB
test_0067.txt AC 11 ms 3680 KiB
test_0068.txt AC 15 ms 3748 KiB
test_0069.txt AC 9 ms 3620 KiB
test_0070.txt AC 11 ms 3700 KiB
test_0071.txt AC 10 ms 3688 KiB
test_0072.txt AC 9 ms 3696 KiB
test_0073.txt AC 10 ms 3696 KiB
test_0074.txt AC 13 ms 3764 KiB
test_0075.txt AC 12 ms 3788 KiB
test_0076.txt AC 11 ms 3692 KiB
test_0077.txt AC 12 ms 3668 KiB
test_0078.txt AC 9 ms 3692 KiB
test_0079.txt AC 10 ms 3704 KiB
test_0080.txt AC 10 ms 3772 KiB
test_0081.txt AC 11 ms 3752 KiB
test_0082.txt AC 11 ms 3712 KiB
test_0083.txt AC 12 ms 3704 KiB
test_0084.txt AC 11 ms 3692 KiB
test_0085.txt AC 11 ms 3704 KiB
test_0086.txt AC 9 ms 3692 KiB
test_0087.txt AC 9 ms 3688 KiB
test_0088.txt AC 10 ms 3696 KiB
test_0089.txt AC 11 ms 3652 KiB
test_0090.txt AC 10 ms 3676 KiB
test_0091.txt AC 10 ms 3816 KiB
test_0092.txt AC 12 ms 3708 KiB
test_0093.txt AC 10 ms 3780 KiB
test_0094.txt AC 10 ms 3556 KiB
test_0095.txt AC 10 ms 3820 KiB
test_0096.txt AC 10 ms 3664 KiB
test_0097.txt AC 10 ms 3692 KiB
test_0098.txt AC 9 ms 3684 KiB
test_0099.txt AC 10 ms 3688 KiB
test_0100.txt AC 12 ms 3712 KiB
test_0101.txt AC 9 ms 3680 KiB
test_0102.txt AC 10 ms 3760 KiB
test_0103.txt AC 12 ms 3788 KiB
test_0104.txt AC 13 ms 3664 KiB
test_0105.txt AC 12 ms 3828 KiB
test_0106.txt AC 12 ms 3708 KiB
test_0107.txt AC 10 ms 3672 KiB
test_0108.txt AC 11 ms 3708 KiB
test_0109.txt AC 10 ms 3820 KiB
test_0110.txt AC 11 ms 3700 KiB
test_0111.txt AC 12 ms 3716 KiB
test_0112.txt AC 10 ms 3740 KiB
test_0113.txt AC 12 ms 3712 KiB
test_0114.txt AC 10 ms 3696 KiB
test_0115.txt AC 12 ms 3752 KiB
test_0116.txt AC 12 ms 3708 KiB
test_0117.txt AC 10 ms 3684 KiB
test_0118.txt AC 11 ms 3700 KiB
test_0119.txt AC 10 ms 3744 KiB
test_0120.txt AC 9 ms 3676 KiB
test_0121.txt AC 9 ms 3740 KiB
test_0122.txt AC 11 ms 3632 KiB
test_0123.txt AC 10 ms 3680 KiB
test_0124.txt AC 10 ms 3624 KiB
test_0125.txt AC 10 ms 3676 KiB
test_0126.txt AC 10 ms 3780 KiB
test_0127.txt AC 9 ms 3696 KiB
test_0128.txt AC 10 ms 3776 KiB
test_0129.txt AC 13 ms 3620 KiB
test_0130.txt AC 11 ms 3824 KiB
test_0131.txt AC 9 ms 3712 KiB
test_0132.txt AC 9 ms 3756 KiB
test_0133.txt AC 10 ms 3688 KiB
test_0134.txt AC 11 ms 3824 KiB
test_0135.txt AC 10 ms 3560 KiB
test_0136.txt AC 10 ms 3756 KiB
test_0137.txt AC 10 ms 3624 KiB
test_0138.txt AC 12 ms 3704 KiB
test_0139.txt AC 12 ms 3668 KiB
test_0140.txt AC 12 ms 3712 KiB
test_0141.txt AC 11 ms 3708 KiB
test_0142.txt AC 12 ms 3704 KiB
test_0143.txt AC 11 ms 3776 KiB
test_0144.txt AC 11 ms 3564 KiB
test_0145.txt AC 8 ms 3672 KiB
test_0146.txt AC 10 ms 3692 KiB
test_0147.txt AC 10 ms 3780 KiB
test_0148.txt AC 10 ms 3688 KiB
test_0149.txt AC 11 ms 3688 KiB