Problem:
負けず嫌いのイクタ君は、最近囲碁盤を使って遊ぶゲームに熱中している。
しかし、囲碁も五目並べも友人に全く勝てないので、あまり有名でない Phutball というゲームの特訓をすることにした。
このゲームは難しいゲームなので、手始めに自分のターンに勝って終局できるかを判定できるように特訓することにした。
ゲームの勝利条件は以下のようなものである。
白石は黒石の置かれている場所にジャンプすることは出来ない。
碁盤の中央の
19 × 15
の部分を用いる。
勝利条件を判定したい碁盤は白石が1つと黒石がいくつか置かれた状態で与えられる。
ゴール地点というのは碁盤の下端か、その下側を指す。（下図を参照せよ。）
ゴール地点に白石を運べば勝利する。
勝利するために以下のようなことを行う。
白石は1回以上ジャンプを行うことができる。
ジャンプは白石に隣接する8方向（上下左右と斜め上、斜め下）の黒石のどれかを飛び越えることで行える。
黒石が隣接していない方向へジャンプすることは出来ない。
飛び越えられた黒石は、1回のジャンプごとに碁盤の上から取り除かれる。
ジャンプしたあとの白石はゴール地点かゲーム盤の上に存在しなければいけない。
黒石が2個以上連続していても、ちょうどそれをまたぐようにジャンプできる。
白石は黒石の置かれている場所にジャンプすることは出来ない。(ジャンプする方向に連続している黒石は必ず飛び越えなくてはならない。)
図の丸印がついている場所へはジャンプすることが可能であり、全てゴール地点であるが、バツ印の場所はゴール地点でもなく、碁盤の内側でもないので、ジャンプすることは出来ない。
あなたの仕事はイクタ君の特訓を手助けするために、ゴールできるかどうかの判定と、ゴールするための最小のジャンプ回数を求めるプログラムを書いてあげる事である。
Input
.OX
で構成された
19 × 15
の盤面が19行で与えられる。
各行は必ず15文字からなり、各文字は次を表す。
"."は空白を表す。
"O"は白石を表す。
"X"は黒石を表す。
Constraints
黒石の数が20以下。
白石は必ず1つだけ存在する。
すでにゴールした状態が入力されることはない。
Output
ゴール可能なら最短の手数を1行に出力せよ。ゴールすることが不可能な場合は-1を出力せよ。
Sample Input 1
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
......O........
......X........
Output for the Sample Input 1
1
白石は黒石を1回ジャンプしてゴールすることができる。
Sample Input 2
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
......O........
...............
Output for the Sample Input 2
-1
白石は移動できないのでゴールできない。
Sample Input 3
...............
...............
...............
...............
...............
...............
...............
...............
...........O...
............X..
.............X.
.............X.
.............X.
...............
..............X
.........X.....
.............X.
......X....X..X
.....X.X.XX.X..
Output for the Sample Input 3
6
ちょうど6回でゴールできる。
ジャンプ毎に分解した画像を以下に示す。
Sample Input 4
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
...............
.....XX........
.....XXXO......
......X........
Output for the Sample Input 4
4

Submitted solutions:

code_snippet: #include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>
#include <cassert>


using namespace std;
//using namespace atcoder;

#define REP(i, n) for (int i=0; i<(n); ++i)
#define RREP(i, n) for (int i=(int)(n)-1; i>=0; --i)
#define FOR(i, a, n) for (int i=(a); i<(n); ++i)
#define RFOR(i, a, n) for (int i=(int)(n)-1; i>=(a); --i)

#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(),(x).end()

#define DUMP(x) cerr<<#x<<" = "<<(x)<<endl
#define DEBUG(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl;

template<class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "[";
    REP(i, SZ(v)) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "]";
}

template<class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    return os << "(" << p.first << " " << p.second << ")";
}

template<class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;
using vvi = vector<vi>;
using vvll = vector<vll>;

const ll MOD = 1e9 + 7;
const int INF = MOD;
const ll LINF = LLONG_MAX / 2;
const ld eps = 1e-9;


// edit

//int dp[20][15][1 << 20];
using State = tuple<int, int, int>;
map<State, int> dp;

void solve() {
    int H = 20, W = 17;
    vector<string> S(20);
    REP(i, 19) {
        cin >> S[i];
    }
    S[19] = "...............";

    vector<vector<int>> fie(H, vector<int>(W, -1)); // field;

    int sy = -1, sx = -1;
    int N = 0;
    {
        int idx = 0;
        REP(i, H) {
            REP(j, W) {
                if (S[i][j] == 'X') {
                    fie[i][j + 1] = idx++;
                }
                if (S[i][j] == 'O') {
                    sy = i, sx = j + 1;
                }
            }
        }
        N = idx;
    }


//    memset(dp, 0, sizeof(dp));
//    for (int i = 0; i < H; ++i) {
//        for (int j = 0; j < W; ++j) {
//            for (int k = 0; k < 1 << N; ++k) {
//                dp[i][j][k] = INF;
//            }
//        }
//    }

//    dp[sy][sx][0] = 0;
    dp[make_tuple(sy, sx, 0)] = 0;


    queue<State> que;
    que.push(State{sy, sx, 0});

    auto is_black = [&](int y, int x, int mask) {
        if (fie[y][x] == -1) return false;
        int val = fie[y][x];
        if (mask >> val & 1) return false;
        return true;
    };

    auto is_inner = [&](int y, int x) {
        return y >= 0 && y < H && x >= 0 && x < W;
    };

    function<tuple<int, int, vector<int>>(int, int, int, int, int)> go = [&](int y, int x, int mask, int dy,
                                                                             int dx) -> tuple<int, int, vector<int>> {
        int cy = y + dy;
        int cx = x + dx;
        vector<int> del;

        while (is_inner(cy, cx) && is_black(cy, cx, mask)) {
//            assert(fie[cy][cx] != -1);
//            assert((mask >> fie[cy][cx] & 1) == 0);

            del.push_back(fie[cy][cx]);
            cy += dy;
            cx += dx;
        }

        if (!is_inner(cy, cx)) return make_tuple(-1, -1, vector<int>());
        if (del.size() == 0) return make_tuple(-1, -1, vector<int>());

        return tuple<int, int, vector<int>>{cy, cx, del};
    };

    while (!que.empty()) {
        auto top = que.front();
        que.pop();
        int y, x, mask;
        tie(y, x, mask) = top;
//        int cost = dp[y][x][mask];
        assert(dp.count(make_tuple(y, x, mask)));
        int cost = dp[make_tuple(y, x, mask)];
        if(y == H - 1 || x == 0 || x == W - 1) continue;

        for (int dy = -1; dy <= 1; ++dy) {
            for (int dx = -1; dx <= 1; ++dx) {
                if (dx == 0 && dy == 0) continue;

                auto tmp = go(y, x, mask, dy, dx);
                int ny, nx;
                vector<int> del;
                tie(ny, nx, del) = tmp;
                if (ny == -1 && nx == -1) continue;

                int nmask = mask;
                for (auto e : del) {
                    assert((nmask & (1 << e)) == 0);
                    nmask |= (1 << e);
                }

//                if (dp[ny][nx][nmask] > cost + 1) {
//                    dp[ny][nx][nmask] = cost + 1;
//                    que.push(State{ny, nx, nmask});
//                }
                if (dp.count(make_tuple(ny, nx, nmask)) == 0) {
//                    dp[ny][nx][nmask] = cost + 1;
                    dp[make_tuple(ny, nx, nmask)] = cost + 1;
                    que.push(State{ny, nx, nmask});
                }
            }
        }
    }

    int ans = INF;
    for (auto kv : dp) {
        int h, w, mask;
        tie(h, w, mask) = kv.first;
        int val = kv.second;
        if (h == H - 1 || (h == H - 2 && w >= 1 && w < W - 1)) {
            chmin(ans, val);
        }

//        if (h >= H - 2) {
//            chmin(ans, val);
//        }
    }
//    for (int w = 0; w < W; ++w) {
//        for (int mask = 0; mask < 1 << N; ++mask) {
////            chmin(ans, dp[H - 1][w][mask]);
//        }
//    }
    if (ans == INF) {
        cout << -1 << endl;
    } else {
        cout << ans << endl;
    }


}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
//    std::ifstream in("input.txt");
//    std::cin.rdbuf(in.rdbuf());

    solve();


    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 8344
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(n);++i)
#define foreach(i,n) for(auto &i:(n))
#define lambda(RES,...) (function<RES(__VA_ARGS__)>) [&](__VA_ARGS__) -> RES
#define method(NAME,RES,...) function<RES(__VA_ARGS__)>NAME =  [&](__VA_ARGS__) -> RES
#define all(x) (x).begin(),(x).end()
#define bit(x) (1ll<<(x))

template<class t>
using priority_queuer = priority_queue<t,vector<t>,greater<t>>;
template<class t>
using vvector = vector<vector<t>>;
using pii = pair<int,int>;
using ll = long long;
template<class t,class u>
bool chmin(t&a,u b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}
template<class t,class u>
bool chmax(t&a,u b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}

ll in(){
    ll res;
    cin >> res;
    return res;
}


template<class t>
t in(){
    t res;
    cin >> res;
    return res;
}


const ll INF = 1e9;

int func(){
    int h = 19;
    int w = 15;
    vvector<int> board(h,vector<int>(w,0));
    int sx;
    int sy;
    rep(i,h){
        rep(j,w){
            char c = in<char>();
            if(c=='O'){
                sx = j;
                sy = i;
            }else if(c=='X'){
                board[i][j] = 1;
            }
        }
    }
    method(isin,bool,int y,int x){
        if(x<0 or y<0 or w<=x or h<=y)return false;
        return true;
    };
    method(isok,bool,int y,int x){
        if(x<0 or y<0 or w<=x)return false;
        return true;
    };
    method(isgoal,bool,int y,int x){
        return h <= y or (h-1<=y and 0<=x and x<w);
    };
    method(func,int,int y,int x){
        if(isgoal(y,x)){
            return 0;
        }
        int dx[]={1,0,-1,-1,-1,0,1,1};
        int dy[]={1,1,1,0,-1,-1,-1,0};
        method(culc,vector<pii>,int dx,int dy){
            int cx = x;
            int cy = y;
            vector<pii> res;
            while(true){
                cx += dx;
                cy += dy;
                if(!isin(cy,cx))break;
                if(board[cy][cx]){
                    res.emplace_back(cy,cx);
                }else{
                    break;
                }
            }
            if(isgoal(cy,cx)){
                res.emplace_back(cy,cx);
                return res;
            }
            if(isok(cy,cx)){
                res.emplace_back(cy,cx);
                return res;
            }
            return vector<pii>(0);
        };
        int res = INF;
        rep(i,8){
            vector<pii> line = culc(dx[i],dy[i]);
            if(line.size()<=1)continue;
            rep(j,line.size()-1){
                board[line[j].first][line[j].second] = 0;
            }
            chmin(res,1+func(line.back().first,line.back().second));
            rep(j,line.size()-1){
                board[line[j].first][line[j].second] = 1;
            }
        }
        return res;
    };
    int res = func(sy,sx);
    if(res==INF)return -1;
    return res;
}

int main(){
    cout << func() << endl;
    return 0;
}
accuracy: 1
time_ms: 1630
memory_kb: 3484
final_rank: 14

code_snippet: #include<bits/stdc++.h>

using ll = long long;
#define var auto

using namespace std;

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){ if(a > b) a = b; }
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){ if(a < b) a = b; }

const int realh = 19;
const int realw = 15;

const int h = realh + 2;
const int w = realw + 2;

int black_count;
int pos_count;
int id[h][w];
vector<string> s(h);

vector<bool> arrived;

int encode(int state, int y, int x){
  return ((y * w + x) << black_count) + state;
}

void decode(int id, int& state, int& y, int& x){
  state = id & ((1 << black_count) - 1);
  var yx = id >> black_count;
  y = yx / w;
  x = yx % w;
}

int dys[] = { -1, -1, -1,  0, 0,  1, 1, 1 };
int dxs[] = { -1,  0,  1, -1, 1, -1, 0, 1 };

bool in(int i, int mx){
  return 0 <= i && i < mx;
}

void solve(){
  for (int i = 1; i <= realh; i++) {
    cin >> s[i];
    s[i] = "." + s[i] + ".";
  }
  s[0] = s[h - 1] = string(w, '.');
  for (int i = 0; i < h; i++){
    for (int j = 0; j < w; j++){
      id[i][j] = -1;
    }
  }

  int sy, sx;
  int sid = 0;
  for (int i = 1; i <= realh; i++){
    for (int j = 1; j <= realw; j++){
      if (s[i][j] == 'X'){
        id[i][j] = sid++;
      }
      else{    
        if (s[i][j] == 'O'){
          sy = i, sx = j;
        }
      }
    }
  }

  black_count = sid;
  arrived = vector<bool>((1 << black_count) * (h * w));

  vector<int> prevs{encode((1 << black_count) - 1, sy, sx)};
  for (int step = 1; prevs.size() != 0; step++){
    vector<int> nexts{};
    for (var&& elem : prevs){
      int sstate, sy, sx;
      decode(elem, sstate, sy, sx);

      for (int i = 0; i < 8; i++){
        var dy = dys[i], dx = dxs[i];
        var y = sy + dy, x = sx + dx;
        var state = sstate;
        bool isin;
        while (in(y, h) && in(x, w)){
          if (s[y][x] != 'X') break;
          if (!(state >> id[y][x] & 1)) break;
          state -= 1 << id[y][x];
          y += dy; x += dx;
        }
        //飛び越えてない
        if (state == sstate) continue;
        //飛び越えてOoBに行くことはないので、飛び越え判定のみでなんとかする
        var code = encode(state, y, x);
        if (arrived[code]) continue;
        arrived[code] = true;
        var xedge = x == 0 || x == w - 1;
        if (y == h - 1 || (y == h - 2 && !xedge)) goto found;
        if (y == 0 || xedge) continue;
        nexts.push_back(code);
      }
    }
    prevs = move(nexts);
    continue;
    found:;
    cout << step << endl;
    goto end;
  }
  cout << -1 << endl;
  end:;
}

int main(){
  solve();
}
accuracy: 1
time_ms: 10
memory_kb: 48924
final_rank: 12

code_snippet: #include<bits/stdc++.h>

using ll = long long;
#define var auto

using namespace std;

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){ if(a > b) a = b; }
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){ if(a < b) a = b; }

const int realh = 19;
const int realw = 15;

const int h = realh + 2;
const int w = realw + 2;

int black_count;
int pos_count;
int id[h][w];
vector<string> s(h);

vector<bool> arrived;

int encode(int state, int y, int x){
  return ((y * w + x) << black_count) + state;
}

void decode(int id, int& state, int& y, int& x){
  state = id & ((1 << black_count) - 1);
  var yx = id >> black_count;
  y = yx / w;
  x = yx % w;
}

int dys[] = { -1, -1, -1,  0, 0,  1, 1, 1 };
int dxs[] = { -1,  0,  1, -1, 1, -1, 0, 1 };

bool in(int i, int mx){
  return 0 <= i && i < mx;
}

void solve(){
  for (int i = 1; i <= realh; i++) {
    cin >> s[i];
    s[i] = "." + s[i] + ".";
  }
  s[0] = s[h - 1] = string(w, '.');
  for (int i = 0; i < h; i++){
    for (int j = 0; j < w; j++){
      id[i][j] = -1;
    }
  }

  int sy, sx;
  int sid = 0;
  for (int i = 1; i <= realh; i++){
    for (int j = 1; j <= realw; j++){
      if (s[i][j] == 'X'){
        id[i][j] = sid++;
      }
      else{    
        if (s[i][j] == 'O'){
          sy = i, sx = j;
        }
      }
    }
  }

  black_count = sid;
  arrived = vector<bool>((1 << black_count) * (h * w));

  vector<int> prevs{encode((1 << black_count) - 1, sy, sx)};
  for (int step = 1; prevs.size() != 0; step++){
    vector<int> nexts{};
    for (var&& elem : prevs){
      int sstate, sy, sx;
      decode(elem, sstate, sy, sx);

      for (int i = 0; i < 8; i++){
        var dy = dys[i], dx = dxs[i];
        var y = sy + dy, x = sx + dx;
        var state = sstate;
        bool isin;
        while (in(y, h) && in(x, w)){
          if (s[y][x] != 'X') break;
          if (!(state >> id[y][x] & 1)) break;
          state -= 1 << id[y][x];
          y += dy; x += dx;
        }
        //飛び越えてない
        if (state == sstate) continue;
        //飛び越えてOoBに行くことはないので、飛び越え判定のみでなんとかする
        var code = encode(state, y, x);
        if (arrived[code]) continue;
        arrived[code] = true;
        var xedge = x == 0 || x == w - 1;
        if (y == h - 1 || y == h) goto found;
        if (y == 0 || xedge) continue;
        nexts.push_back(code);
      }
    }
    prevs = move(nexts);
    continue;
    found:;
    cout << step << endl;
    goto end;
  }
  cout << -1 << endl;
  end:;
}

int main(){
  solve();
}
accuracy: 0.0967741935483871
time_ms: 10
memory_kb: 48528
final_rank: 18

code_snippet: #include<bits/stdc++.h>

using ll = long long;
#define var auto

using namespace std;

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){ if(a > b) a = b; }
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){ if(a < b) a = b; }

const int realh = 19;
const int realw = 15;

const int h = realh + 2;
const int w = realw + 2;

int black_count;
int pos_count;
int id[h][w];
vector<string> s(h);

vector<bool> arrived;

int encode(int state, int y, int x){
  return ((y * w + x) << black_count) + state;
}

void decode(int id, int& state, int& y, int& x){
  state = id & ((1 << black_count) - 1);
  var yx = id >> black_count;
  y = yx / w;
  x = yx % w;
}

int dys[] = { -1, -1, -1,  0, 0,  1, 1, 1 };
int dxs[] = { -1,  0,  1, -1, 1, -1, 0, 1 };

bool in(int i, int mx){
  return 0 <= i && i < mx;
}

void solve(){
  for (int i = 1; i <= realh; i++) {
    cin >> s[i];
    s[i] = "." + s[i] + ".";
  }
  s[0] = s[h - 1] = string(w, '.');
  for (int i = 0; i < h; i++){
    for (int j = 0; j < w; j++){
      id[i][j] = -1;
    }
  }

  int sy, sx;
  int sid = 0;
  for (int i = 1; i <= realh; i++){
    for (int j = 1; j <= realw; j++){
      if (s[i][j] == 'X'){
        id[i][j] = sid++;
      }
      else{    
        if (s[i][j] == 'O'){
          sy = i, sx = j;
        }
      }
    }
  }

  black_count = sid;
  arrived = vector<bool>((1 << black_count) * (h * w));

  vector<int> prevs{encode((1 << black_count) - 1, sy, sx)};
  for (int step = 1; prevs.size() != 0; step++){
    vector<int> nexts{};
    for (var&& elem : prevs){
      int sstate, sy, sx;
      decode(elem, sstate, sy, sx);

      for (int i = 0; i < 8; i++){
        var dy = dys[i], dx = dxs[i];
        var y = sy + dy, x = sx + dx;
        var state = sstate;
        bool isin;
        while (in(y, h) && in(x, w)){
          if (s[y][x] != 'X') break;
          if (!(state >> id[y][x] & 1)) break;
          state -= 1 << id[y][x];
          y += dy; x += dx;
        }
        //飛び越えてない
        if (state == sstate) continue;
        //飛び越えてOoBに行くことはないので、飛び越え判定のみでなんとかする
        var code = encode(state, y, x);
        if (arrived[code]) continue;
        arrived[code] = true;
        var xedge = x == 0 || x == w - 1;
        if (y == h - 1 || (y == h && !xedge)) goto found;
        if (y == 0 || xedge) continue;
        nexts.push_back(code);
      }
    }
    prevs = move(nexts);
    continue;
    found:;
    cout << step << endl;
    goto end;
  }
  cout << -1 << endl;
  end:;
}

int main(){
  solve();
}
accuracy: 0.0967741935483871
time_ms: 10
memory_kb: 48552
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(n);++i)
#define foreach(i,n) for(auto &i:(n))
#define lambda(RES,...) (function<RES(__VA_ARGS__)>) [&](__VA_ARGS__) -> RES
#define method(NAME,RES,...) function<RES(__VA_ARGS__)>NAME =  [&](__VA_ARGS__) -> RES
#define all(x) (x).begin(),(x).end()
#define bit(x) (1ll<<(x))

template<class t>
using priority_queuer = priority_queue<t,vector<t>,greater<t>>;
template<class t>
using vvector = vector<vector<t>>;
using pii = pair<int,int>;
using ll = long long;
template<class t,class u>
bool chmin(t&a,u b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}
template<class t,class u>
bool chmax(t&a,u b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}

ll in(){
    ll res;
    cin >> res;
    return res;
}


template<class t>
t in(){
    t res;
    cin >> res;
    return res;
}


const ll INF = 1e9;

int func(){
    int h = 19;
    int w = 15;
    vvector<int> board(h,vector<int>(w,0));
    int sx;
    int sy;
    rep(i,h){
        rep(j,w){
            char c = in<char>();
            if(c=='O'){
                sx = j;
                sy = i;
            }else if(c=='X'){
                board[i][j] = 1;
            }
        }
    }
    method(isin,bool,int y,int x){
        if(x<0 or y<0 or w<=x or h<=y)return false;
        return true;
    };
    method(isok,bool,int y,int x){
        if(x<0 or y<0 or w<=x)return false;
        return true;
    };
    method(isgoal,bool,int y,int x){
        return h <= y or (h-1<=y and 0<=x and x<w);
    };
    method(func,int,int y,int x){
        if(isgoal(y,x)){
            return 0;
        }
        int dx[]={1,0,-1,-1,-1,0,1,1};
        int dy[]={1,1,1,0,-1,-1,-1,0};
        method(culc,vector<pii>,int dx,int dy){
            int cx = x;
            int cy = y;
            vector<pii> res;
            while(true){
                cx += dx;
                cy += dy;
                if(!isin(cy,cx))break;
                if(board[cy][cx]){
                    res.emplace_back(cy,cx);
                }else{
                    break;
                }
            }
            if(isgoal(cy,cx)){
                res.emplace_back(cy,cx);
                return res;
            }
            if(isok(cy,cx)){
                res.emplace_back(cy,cx);
                return res;
            }
            return vector<pii>(0);
        };
        int res = INF;
        rep(i,8){
            vector<pii> line = culc(dx[i],dy[i]);
            if(line.size()<=1)continue;
            rep(j,line.size()-1){
                board[line[j].first][line[j].second] = 0;
            }
            chmin(res,1+func(line.back().first,line.back().second));
            rep(j,line.size()-1){
                board[line[j].first][line[j].second] = 1;
            }
        }
        return res;
    };
    int res = func(sy,sx);
    if(res==INF)return -1;
    return res;
}

int main(){
    cout << func() << endl;
    return 0;
}
accuracy: 1
time_ms: 1580
memory_kb: 3488
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
 
#define int long long
#define REP(i, n) for ( int i = 0; i < (n); i++ )

const int H = 19, W = 15;
const int dx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const int dy[8] = {-1, -1, 0, 1, 1, 1, 0, -1};

struct State {
  int x, y, bit, cost;
  State(int x, int y, int bit, int cost): x(x), y(y), bit(bit), cost(cost) {}
};

int state_to_int(int x, int y, int bit) {
  return bit*(H*W) + x*H + y;  
}

bool over_grid(int x, int y) {
  if ( x < 0 || y < 0 || x >= W || y >= H ) return true;
  return false;  
}

vector<vector<int> > grid(H, vector<int>(W));
int sx, sy;

int bfs() {
  unordered_set<int> used;
  queue<State> Q;
  Q.push(State(sx, sy, 0, 0));
  
  while ( !Q.empty() ) {
    State s = Q.front(); Q.pop();
    int x = s.x, y = s.y, bit = s.bit, cost = s.cost;

    // cout << x << " " << y << " " << bit << " " << cost << endl;    

    if ( y >= H || (y == H-1 && !over_grid(x, y)) ) {
      return cost;
    }


    if ( over_grid(x, y) ) continue;        
    if ( used.count(state_to_int(x, y, bit)) ) continue;
    used.insert(state_to_int(x, y, bit));

    for ( int i = 0; i < 8; i++ ) {
      int nx = x+dx[i], ny = y+dy[i];
      int nbit = bit;
      if ( over_grid(nx, ny) || grid[ny][nx] < 0 || bit&(1<<grid[ny][nx]) ) continue;
      while ( !over_grid(nx, ny) && grid[ny][nx] >= 0 && !(bit&(1<<grid[ny][nx])) ) {
	nbit |= (1<<grid[ny][nx]);	
	nx += dx[i]; ny += dy[i];
      }
      Q.push(State(nx, ny, nbit, cost+1));      
    }
  }

  return -1;  
}
 
signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);

  int cnt = 0;
  REP(i, H) {
    string s;
    cin >> s;
    REP(j, W) {
      if ( s[j] == 'X' ) {
	grid[i][j] = cnt++;
      } else {
	grid[i][j] = -1;
	if ( s[j] == 'O' ) {
	  sx = j; sy = i;	  
	}
      }
    }
  }

  int ans = bfs();
  cout << ans << endl;  

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7244
final_rank: 4

code_snippet: #include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}
template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>b)return 0; a=b; return 1;}
#define bitUP(x,a) ((x>>a)&1)
int dx[8]={0,1,0,-1,1,-1,1,-1}, dy[8]={1,0,-1,0,1,1,-1,-1};
long double eps = 1e-18;
long double pi = acos(-1);



signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    char C[20][16];
    int rev[20][16];
    pair<int,int> black[22];
    int num_black;
    int H=19,W=15;
    int sh,sw;
    int idx=0;
    for(int h=0;h<H;h++){
        for(int w=0;w<W;w++){
            cin>>C[h][w];
            if(C[h][w]=='O'){
                sh=h;
                sw=w;
            }
            if(C[h][w]=='X'){
                black[idx]=pair<int,int>(h,w);
                rev[h][w]=idx++;
            }
        }
    }
    num_black=idx;
    //285*2^20
    queue<tuple<int,int,int>> que;
    que.emplace(sh,sw,(1<<num_black)-1);
    using T=tuple<int,int,int>;
    map<tuple<int,int,int>,int> dis;
    dis[T(sh,sw,(1<<num_black)-1)]=0;
    while(!que.empty()){
        int S;
        tie(sh,sw,S)=que.front(); que.pop();
        for(int i=0;i<num_black;i++){
            int j=bitUP(S,i);
            char c;
            if(j) c='X';
            else c='.';
            C[black[i].first][black[i].second]=c;
        }

        for(int d=0;d<8;d++){
            int deleted=0;
            int nh=sh+dx[d],nw=sw+dy[d];
            if(nh<0 or nw<0 or nh==H or nw==W or C[nh][nw]!='X') continue;

            while(not (nh<0 or nw<0 or nh==H or nw==W) and C[nh][nw]=='X'){
                int t=rev[nh][nw];
                deleted|=(1<<t);
                nh+=dx[d],nw+=dy[d];
            }
            if((nh>=H-1 and nw<=W-1 and nw>=0) or nh==H){
                cout<<dis[T(sh,sw,S)]+1<<endl;
                //cout<<deleted<<endl;
                return 0;
            }
            if(nh<0 or nw<0 or nh==H or nw==W) continue;
            int nS=(S^deleted);
            if(dis.find(T(nh,nw,nS))==dis.end()){
                dis[T(nh,nw,nS)]=dis[T(sh,sw,S)]+1;
                que.emplace(nh,nw,nS);
            }
        }
    }
    cout<<-1<<endl;

}
accuracy: 1
time_ms: 30
memory_kb: 8496
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
vector<int> dy = {1, 0, -1, 0, 1, 1, -1, -1};
vector<int> dx = {0, 1, 0, -1, 1, -1, 1, -1};
const int INF = 10000000;
int dfs(vector<vector<char>> &a, int y, int x){
  if (y >= 19){
    return 0;
  }
  int ans = INF;
  for (int i = 0; i < 8; i++){
    int cy = y + dy[i];
    int cx = x + dx[i];
    vector<pair<int, int>> P;
    while (a[cy][cx] == 'X'){
      a[cy][cx] = '.';
      P.push_back(make_pair(cy, cx));
      cy += dy[i];
      cx += dx[i];
    }
    if (a[cy][cx] == '.' && !P.empty()){
      ans = min(ans, dfs(a, cy, cx) + 1);
    }
    int cnt = P.size();
    for (int j = 0; j < cnt; j++){
      a[P[j].first][P[j].second] = 'X';
    }
  }
  return ans;
}
int main(){
  vector<vector<char>> a(21, vector<char>(17, '#'));
  for (int i = 1; i <= 19; i++){
    for (int j = 1; j <= 15; j++){
      cin >> a[i][j];
    }
  }
  for (int i = 0; i < 17; i++){
    a[20][i] = '.';
  }
  int y, x;
  for (int i = 1; i <= 19; i++){
    for (int j = 1; j <= 15; j++){
      if (a[i][j] == 'O'){
        y = i;
        x = j;
      }
    }
  }
  int ans = dfs(a, y, x);
  if (ans == INF){
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 3164
final_rank: 3

code_snippet: #include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}

int dx[]={-1,0,1,1,1,0,-1,-1};
int dy[]={-1,-1,-1,0,1,1,1,0};

int h=19,w=15;
int n;

char fi[19][15];
vector<pair<int,int>> v;
map<pair<int,int>,int> mp;

bool is_in(int x,int y){
	return 0<=x&&x<h&&0<=y&&y<w;
}

int solve(){
	queue<pair<pair<int,int>,pair<int,int>>> q;
	vector<bool> used(1<<n,false);
	for(int i=0;i<n;i++){
		for(int j=0;j<8;j++){
			auto now=v[i];
			now.first+=dx[j];
			now.second+=dy[j];
			int nx=now.first,ny=now.second;
			if(is_in(nx,ny)&&fi[nx][ny]=='O'&&!used[(1<<n)-1]){
				q.push(make_pair(make_pair((1<<n)-1,0),make_pair(i,j)));
				used[(1<<n)-1]=1;
			}
		}
	}
	while(q.size()){
		auto p=q.front(); q.pop();
		for(int i=0;i<8;i++){
			bool jump=0;
			auto now=p;
			now.first.second++;
			int nx=v[now.second.first].first+dx[now.second.second];
			int ny=v[now.second.first].second+dy[now.second.second];
			now.second.second=i;
			while(is_in(nx,ny)){
				nx+=dx[i],ny+=dy[i];
				if(!is_in(nx,ny)||mp.find(make_pair(nx,ny))==mp.end()||!(now.first.first>>mp[make_pair(nx,ny)]&1)){
					break;
				}
				jump=true;
				now.second.first=mp[make_pair(nx,ny)];
				now.first.first-=(1<<now.second.first);
			}
			if(!jump)continue;
			if(nx==19||(nx==18&&is_in(nx,ny))){
				return now.first.second;
			}
			if(!is_in(nx,ny))continue;
			if(!used[now.first.first]){
				q.push(now);
				used[now.first.first]=1;
			}
		}
	}
	return -1;
}

int main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	for(int i=0;i<h;i++){
		for(int j=0;j<w;j++){
			cin >> fi[i][j];
			if(fi[i][j]=='X'){
				mp[make_pair(i,j)]=v.size();
				v.push_back(make_pair(i,j));
			}
		}
	}
	n=v.size();
	cout << solve() << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3320
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=55,INF=1<<30;
int ans=-1;
int H=20,W=17;

vector<int> dh={-1,0,1,1,1,0,-1,-1},dw={1,1,1,0,-1,-1,-1,0};

set<vector<pair<int,int>>> SE;

void BFS(vector<pair<int,int>> &s){
    queue<pair<vector<pair<int,int>>,int>> Q;
    Q.push(mp(s,0));
    
    while(!Q.empty()){
        auto a=Q.front();Q.pop();
        
        if(SE.count(a.fi)) continue;
        SE.insert(a.fi);
        
        vector<string> S(H,string(W,'.'));
        
        int sh,sw;
        
        for(auto x:a.fi){
            if(x.fi>=100){
                S[x.fi-100][x.se-100]='O';
                sh=x.fi-100;
                sw=x.se-100;
            }
            else S[x.fi][x.se]='X';
        }
        
        for(int j=0;j<W;j++){
            if(S[H-1][j]=='O'){
                ans=a.se;
                while(!Q.empty()) Q.pop();
            }
            if(j>=1&&j<=15&&S[H-2][j]=='O'){
                ans=a.se;
                while(!Q.empty()) Q.pop();
            }
        }
        if(ans!=-1) break;
        
        for(int i=0;i<H;i++){
            for(int j=0;j<W;j++){
                if(S[i][j]=='O'){
                    sh=i;
                    sw=j;
                }
            }
        }
        
        if(sw==0||sw==W-1) continue;
        
        for(int k=0;k<8;k++){
            int toh=sh+dh[k],tow=sw+dw[k];
            while(toh>=0&&toh<H&&tow>=0&&tow<W&&S[toh][tow]=='X'){
                toh+=dh[k];
                tow+=dw[k];
            }
            if(toh==sh+dh[k]&&tow==sw+dw[k]) continue;
            
            vector<string> T=S;
            T[sh][sw]='.';
            toh=sh+dh[k];tow=sw+dw[k];
            while(toh>=0&&toh<H&&tow>=0&&tow<W&&S[toh][tow]=='X'){
                T[toh][tow]='.';
                toh+=dh[k];
                tow+=dw[k];
            }
            T[toh][tow]='O';
            
            vector<pair<int,int>> to;
            
            for(int i=0;i<H;i++){
                for(int j=0;j<W;j++){
                    char c=T[i][j];
                    if(c=='O') to.push_back(mp(100+i,100+j));
                    if(c=='X') to.push_back(mp(i,j));
                }
            }
            
            Q.push(mp(to,a.se+1));
        }
    }
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    vector<pair<int,int>> s;
    for(int i=0;i<19;i++){
        for(int j=1;j<=15;j++){
            char c;cin>>c;
            if(c=='O') s.push_back(mp(100+i,100+j));
            if(c=='X') s.push_back(mp(i,j));
        }
    }
    
    BFS(s);
    
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 460
memory_kb: 17388
final_rank: 10

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

//int N, M, K, H, W, L, R;
long long int N, M, K, H, W, L, R;

int Search(vector<string>&s, int y, int x) {
	int ret = MOD;
	for (int i = -1; i <= 1; i++) {
		for (int j = -1; j <= 1; j++) {
			if (i == 0 && j == 0)continue;
			bool flag = false;
			int ny = y + i, nx = x + j;
			while (ny >= 0 && ny < H&&nx >= 0 && nx < W&&s[ny][nx] == 'X') {
				flag = true;
				s[ny][nx] = '.';
				ny += i, nx += j;
			}
			if (flag&&ny >= 0 && ny < H&& nx >= 0 && nx < W) {
				ret = min(ret, Search(s, ny, nx));
			}
			if (flag&&(ny + 1 > H||(ny+1==H&&nx>=0&&nx<W))) {
				ret = 0;
			}
			ny -= i, nx -= j;
			while (ny != y || nx != x) {
				s[ny][nx] = 'X';
				ny -= i, nx -= j;
			}
		}
	}
	return ret + 1;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	H = 19, W = 15;
	vector<string>s(H);
	for (auto &i : s)cin >> i;
	int sy, sx;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (s[i][j] == 'O') {
				sy = i,sx = j, s[i][j] = '.';
			}
		}
	}
	int ans = Search(s, sy, sx);
	if (ans >= MOD)ans = -1;
	cout << ans << endl;
}
accuracy: 1
time_ms: 300
memory_kb: 3256
final_rank: 9

code_snippet: #define  _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#pragma comment (linker, "/STACK:526000000")

#include "bits/stdc++.h"

using namespace std;
typedef string::const_iterator State;
#define eps 1e-5L
#define MAX_MOD 1000000007LL
#define GYAKU 500000004LL
#define MOD 998244353LL
#define pb push_back
#define mp make_pair
typedef long long ll;
#define REP(a,b) for(long long (a) = 0;(a) < (b);++(a))
#define ALL(x) (x).begin(),(x).end()

// geometry library

typedef complex<long double> Point;
typedef pair<complex<long double>, complex<long double>> Line;

typedef struct Circle {
    complex<long double> center;
    long double r;
}Circle;

long double dot(Point a, Point b) {
    return (a.real() * b.real() + a.imag() * b.imag());
}
long double cross(Point a, Point b) {
    return (a.real() * b.imag() - a.imag() * b.real());
}

long double Dist_Line_Point(Line a, Point b) {
    if (dot(a.second - a.first, b - a.first) < eps) return abs(b - a.first);
    if (dot(a.first - a.second, b - a.second) < eps) return abs(b - a.second);
    return abs(cross(a.second - a.first, b - a.first)) / abs(a.second - a.first);
}

int is_intersected_ls(Line a, Line b) {
    return (cross(a.second - a.first, b.first - a.first) * cross(a.second - a.first, b.second - a.first) < eps) &&
        (cross(b.second - b.first, a.first - b.first) * cross(b.second - b.first, a.second - b.first) < eps);
}

Point intersection_l(Line a, Line b) {
    Point da = a.second - a.first;
    Point db = b.second - b.first;
    return a.first + da * cross(db, b.first - a.first) / cross(db, da);
}

long double Dist_Line_Line(Line a, Line b) {
    if (is_intersected_ls(a, b) == 1) {
        return 0;
    }
    return min({ Dist_Line_Point(a,b.first), Dist_Line_Point(a,b.second),Dist_Line_Point(b,a.first),Dist_Line_Point(b,a.second) });
}

pair<Point, Point> intersection_Circle_Circle(Circle a, Circle b) {
    long double dist = abs(a.center - b.center);
    assert(dist <= eps + a.r + b.r);
    assert(dist + eps >= abs(a.r - b.r));
    Point target = b.center - a.center;
    long double pointer = target.real() * target.real() + target.imag() * target.imag();
    long double aa = pointer + a.r * a.r - b.r * b.r;
    aa /= 2.0L;
    Point l{ (aa * target.real() + target.imag() * sqrt(pointer * a.r * a.r - aa * aa)) / pointer,
            (aa * target.imag() - target.real() * sqrt(pointer * a.r * a.r - aa * aa)) / pointer };
    Point r{ (aa * target.real() - target.imag() * sqrt(pointer * a.r * a.r - aa * aa)) / pointer,
        (aa * target.imag() + target.real() * sqrt(pointer * a.r * a.r - aa * aa)) / pointer };
    r = r + a.center;
    l = l + a.center;
    return mp(l, r);
}

//end of geometry

template<typename A>
A pows(A val, ll b) {
    assert(b >= 1);
    A ans = val;
    b--;
    while (b) {
        if (b % 2) {
            ans *= val;
        }
        val *= val;
        b /= 2LL;
    }
    return ans;
}

template<typename A>
class Compressor {
public:
    bool is_zipped = false;
    map<A, ll> zipper;
    map<ll, A> unzipper;
    queue<A> fetcher;
    Compressor() {
        is_zipped = false;
        zipper.clear();
        unzipper.clear();
    }
    void add(A now) {
        assert(is_zipped == false);
        zipper[now] = 1;
        fetcher.push(now);
    }
    void exec() {
        assert(is_zipped == false);
        int cnt = 0;
        for (auto i = zipper.begin(); i != zipper.end(); ++i) {
            i->second = cnt;
            unzipper[cnt] = i->first;
            cnt++;
        }
        is_zipped = true;
    }
    ll fetch() {
        assert(is_zipped == true);
        A hoge = fetcher.front();
        fetcher.pop();
        return zipper[hoge];
    }
    ll zip(A now) {
        assert(is_zipped == true);
        assert(zipper.find(now) != zipper.end());
        return zipper[now];
    }
    A unzip(ll a) {
        assert(is_zipped == true);
        assert(a < unzipper.size());
        return unzipper[a];
    }
    ll next(A now) {
        auto x = zipper.upper_bound(now);
        if (x == zipper.end()) return zipper.size();
        return (ll)((*x).second);
    }
    ll back(A now) {
        auto x = zipper.lower_bound(now);
        if (x == zipper.begin()) return -1;
        x--;
        return (ll)((*x).second);
    }
};

template<typename A>
class Matrix {
public:
    vector<vector<A>> data;
    Matrix(vector<vector<A>> a) :data(a) {

    }
    Matrix operator + (const Matrix obj) {
        vector<vector<A>> ans;
        assert(obj.data.size() == this->data.size());
        assert(obj.data[0].size() == this->data[0].size());
        REP(i, obj.data.size()) {
            ans.push_back(vector<A>());
            REP(q, obj.data[i].size()) {
                A hoge = obj.data[i][q] + (this->data[i][q]);
                ans.back().push_back(hoge);
            }
        }
        return Matrix(ans);
    }
    Matrix operator - (const Matrix obj) {
        vector<vector<A>> ans;
        assert(obj.data.size() == this->data.size());
        assert(obj.data[0].size() == this->data[0].size());
        REP(i, obj.data.size()) {
            ans.push_back(vector<A>());
            REP(q, obj.data[i].size()) {
                A hoge = this->data[i][q] - obj.data[i][q];
                ans.back().push_back(hoge);
            }
        }
        return Matrix(ans);
    }
    Matrix operator * (const Matrix obj) {
        vector<vector<A>> ans;
        assert(obj.data.size() == this->data[0].size());
        REP(i, this -> data.size()) {
            ans.push_back(vector<A>());
            REP(q, obj.data[0].size()) {
                A hoge = (this->data[i][0]) * (obj.data[0][q]);
                for (int t = 1; t < obj.data[i].size(); ++t) {
                    hoge += this->data[i][t] * obj.data[t][q];
                }
                ans.back().push_back(hoge);
            }
        }
        return Matrix(ans);
    }
    Matrix& operator *= (const Matrix obj) {
        *this = (*this * obj);
        return *this;
    }
    Matrix& operator += (const Matrix obj) {
        *this = (*this + obj);
        return *this;
    }
    Matrix& operator -= (const Matrix obj) {
        *this = (*this - obj);
        return *this;
    }
};

class modint {
public:
    using u64 = std::uint_fast64_t;
    u64 value = 0;
    u64 mod;
    modint(ll a, ll b) : value(((a% b) + 2 * b) % b), mod(b) {

    }
    modint operator+(const modint rhs) const {
        return modint(*this) += rhs;
    }
    modint operator-(const modint rhs) const {
        return modint(*this) -= rhs;
    }
    modint operator*(const modint rhs) const {
        return modint(*this) *= rhs;
    }
    modint operator/(const modint rhs) const {
        return modint(*this) /= rhs;
    }
    modint& operator+=(const modint rhs) {
        assert(rhs.mod == mod);
        value += rhs.value;
        if (value >= mod) {
            value -= mod;
        }
        return *this;
    }
    modint& operator-=(const modint rhs) {
        assert(rhs.mod == mod);
        if (value < rhs.value) {
            value += mod;
        }
        value -= rhs.value;
        return *this;
    }
    modint& operator*=(const modint rhs) {
        assert(rhs.mod == mod);
        value = (value * rhs.value) % mod;
        return *this;
    }
    modint& operator/=(modint rhs) {
        assert(rhs.mod == mod);
        ll rem = mod - 2;
        while (rem) {
            if (rem % 2) {
                *this *= rhs;
            }
            rhs *= rhs;
            rem /= 2LL;
        }
        return *this;
    }
    bool operator <(modint rhs) const {
        return value < rhs.value;
    }
    friend ostream& operator<<(ostream& os, modint& p) {
        os << p.value;
        return (os);
    }
};

class Dice {
public:
    vector<ll> vertexs;
    //Up: 0,Left: 1,Center: 2,Right: 3,Adj: 4, Down: 5
    Dice(vector<ll> init) :vertexs(init) {

    }
    //Look from Center
    void RtoL() {
        for (int q = 1; q < 4; ++q) {
            swap(vertexs[q], vertexs[q + 1]);
        }
    }
    void LtoR() {
        for (int q = 3; q >= 1; --q) {
            swap(vertexs[q], vertexs[q + 1]);
        }
    }
    void UtoD() {
        swap(vertexs[5], vertexs[4]);
        swap(vertexs[2], vertexs[5]);
        swap(vertexs[0], vertexs[2]);
    }
    void DtoU() {
        swap(vertexs[0], vertexs[2]);
        swap(vertexs[2], vertexs[5]);
        swap(vertexs[5], vertexs[4]);
    }
    bool ReachAble(Dice now) {
        set<Dice> hoge;
        queue<Dice> next;
        next.push(now);
        hoge.insert(now);
        while (next.empty() == false) {
            Dice seeing = next.front();
            next.pop();
            if (seeing == *this) return true;
            seeing.RtoL();
            if (hoge.count(seeing) == 0) {
                hoge.insert(seeing);
                next.push(seeing);
            }
            seeing.LtoR();
            seeing.LtoR();
            if (hoge.count(seeing) == 0) {
                hoge.insert(seeing);
                next.push(seeing);
            }
            seeing.RtoL();
            seeing.UtoD();
            if (hoge.count(seeing) == 0) {
                hoge.insert(seeing);
                next.push(seeing);
            }
            seeing.DtoU();
            seeing.DtoU();
            if (hoge.count(seeing) == 0) {
                hoge.insert(seeing);
                next.push(seeing);
            }
        }
        return false;
    }
    bool operator ==(const Dice& a) {
        for (int q = 0; q < 6; ++q) {
            if (a.vertexs[q] != (*this).vertexs[q]) {
                return false;
            }
        }
        return true;
    }
    bool operator <(const Dice& a) const {
        return (*this).vertexs < a.vertexs;
    }
};

pair<Dice, Dice> TwoDimDice(int center, int up) {
    int target = 1;
    while (true) {
        if (center != target && 7 - center != target && up != target && 7 - up != target) {
            break;
        }
        target++;
    }
    return mp(Dice(vector<ll>{up, target, center, 7 - target, 7 - center, 7 - up}), Dice(vector<ll>{up, 7 - target, center, target, 7 - center, 7 - up}));
}

tuple<Dice, Dice, Dice, Dice> OneDimDice(int center) {
    int bo = min(center, 7 - center);
    pair<int, int> goa;
    if (bo == 1) {
        goa = mp(2, 3);
    }
    else if (bo == 2) {
        goa = mp(1, 3);
    }
    else if (bo == 3) {
        goa = mp(1, 2);
    }
    tuple<Dice, Dice, Dice, Dice> now = make_tuple(Dice(vector<ll>{goa.first, goa.second, center, 7 - goa.second, 7 - center, 7 - goa.first}),
        Dice(vector<ll>{goa.first, 7 - goa.second, center, goa.second, 7 - center, 7 - goa.first}),
        Dice(vector<ll>{7 - goa.first, goa.second, center, 7 - goa.second, 7 - center, goa.first}),
        Dice(vector<ll>{7 - goa.first, 7 - goa.second, center, goa.second, 7 - center, goa.first}));
    return now;
}

template<typename A, typename B>
class Dijkstra {
public:
    vector<vector<pair<int, A>>> vertexs;
    B Cost_Function;
    Dijkstra(int n, B cost) : Cost_Function(cost) {
        vertexs = vector<vector<pair<int, A>>>(n, vector<pair<int, A>>{});
    }
    ~Dijkstra() {
        vertexs.clear();
    }
    void add_edge(int a, int b, A c) {
        vertexs[a].push_back(mp(b, c));
    }
    vector<ll> build_result(int StartPoint) {
        vector<ll> dist(vertexs.size(), 2e18);
        dist[StartPoint] = 0;
        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> next;
        next.push(make_pair(0, StartPoint));
        while (next.empty() == false) {
            pair<ll, int> now = next.top();
            next.pop();
            if (dist[now.second] != now.first) continue;
            for (auto x : vertexs[now.second]) {
                ll now_cost = now.first + Cost_Function(x.second);
                if (dist[x.first] > now_cost) {
                    dist[x.first] = now_cost;
                    next.push(mp(now_cost, x.first));
                }
            }
        }
        return dist;
    }
};

class Dinic {
public:
    struct edge {
        int to;
        int cap;
        int rev;
    };
    vector<vector<edge>> Graph;
    vector<int> level;
    vector<int> itr;
    Dinic(int n) {
        Graph = vector<vector<edge>>(n, vector<edge>());
    }
    void add_edge(int a, int b, int cap) {
        Graph[a].push_back(edge{ b, cap ,(int)Graph[b].size() });
        Graph[b].push_back(edge{ a,0,(int)Graph[a].size() - 1 });
    }
    void bfs(int s) {
        level = vector<int>(Graph.size(), -1);
        level[s] = 0;
        queue<int> next;
        next.push(s);
        while (next.empty() == false) {
            int now = next.front();
            next.pop();
            for (auto x : Graph[now]) {
                if (x.cap == 0) continue;
                if (level[x.to] == -1) {
                    level[x.to] = level[now] + 1;
                    next.push(x.to);
                }
            }
        }
    }
    int dfs(int now, int goal, int val) {
        if (goal == now) return val;
        for (int& i = itr[now]; i < (int)Graph[now].size(); ++i) {
            edge& target = Graph[now][i];
            if (target.cap > 0 && level[now] < level[target.to]) {
                int d = dfs(target.to, goal, min(val, target.cap));
                if (d > 0) {
                    target.cap -= d;
                    Graph[target.to][target.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    int run(int s, int t) {
        int ans = 0;
        int f = 0;
        while (bfs(s), level[t] >= 0) {
            itr = vector<int>(Graph.size(), 0);
            while ((f = dfs(s, t, 1e9)) > 0) {
                ans += f;
            }
        }
        return ans;
    }
};

//by ei1333
//https://ei1333.github.io/luzhiled/snippets/structure/segment-tree.html
template< typename Monoid >
struct SegmentTree {
    using F = function< Monoid(Monoid, Monoid) >;

    int sz;
    vector< Monoid > seg;

    const F f;
    const Monoid M1;

    SegmentTree(int n, const F f, const Monoid& M1) : f(f), M1(M1) {
        sz = 1;
        while (sz < n) sz <<= 1;
        seg.assign(2 * sz + 1, M1);
    }

    void set(int k, const Monoid& x) {
        seg[k + sz] = x;
    }

    void build() {
        for (int k = sz - 1; k > 0; k--) {
            seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    void update(int k, const Monoid& x) {
        k += sz;
        seg[k] = x;
        while (k >>= 1) {
            seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
        }
    }

    Monoid query(int a, int b) {
        Monoid L = M1, R = M1;
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1) L = f(L, seg[a++]);
            if (b & 1) R = f(seg[--b], R);
        }
        return f(L, R);
    }

    Monoid operator[](const int& k) const {
        return seg[k + sz];
    }

    template< typename C >
    int find_subtree(int a, const C& check, Monoid& M, bool type) {
        while (a < sz) {
            Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
            if (check(nxt)) a = 2 * a + type;
            else M = nxt, a = 2 * a + 1 - type;
        }
        return a - sz;
    }


    template< typename C >
    int find_first(int a, const C& check) {
        Monoid L = M1;
        if (a <= 0) {
            if (check(f(L, seg[1]))) return find_subtree(1, check, L, false);
            return -1;
        }
        int b = sz;
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1) {
                Monoid nxt = f(L, seg[a]);
                if (check(nxt)) return find_subtree(a, check, L, false);
                L = nxt;
                ++a;
            }
        }
        return -1;
    }

    template< typename C >
    int find_last(int b, const C& check) {
        Monoid R = M1;
        if (b >= sz) {
            if (check(f(seg[1], R))) return find_subtree(1, check, R, true);
            return -1;
        }
        int a = sz;
        for (b += sz; a < b; a >>= 1, b >>= 1) {
            if (b & 1) {
                Monoid nxt = f(seg[--b], R);
                if (check(nxt)) return find_subtree(b, check, R, true);
                R = nxt;
            }
        }
        return -1;
    }
};

unsigned long xor128() {
    static unsigned long x = 123456789, y = 362436069, z = 521288629, w = 88675123;
    unsigned long t = (x ^ (x << 11));
    x = y; y = z; z = w;
    return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

void init() {
    iostream::sync_with_stdio(false);
    cout << fixed << setprecision(20);
}

#define int long long

void solve() {
    vector<pair<int, int>> batu;
    queue<pair<pair<int,int>,pair<int,int>>> next;
    REP(i, 19) {
        string s;
        cin >> s;
        REP(q, s.length()) {
            if (s[q] == 'O') {
                next.push(mp(mp(i, q), mp(0LL, 0LL)));
            }
            else if (s[q] == 'X') {
                batu.push_back(mp(i, q));
            }
        }
    }
    int grid[30][30] = {};
    while (next.empty() == false) {
        pair<int, int> place = next.front().first;
        int black = next.front().second.first;
        int cost = next.front().second.second;
        next.pop();

        if (place.first == 19||(place.first == 18&&place.second >= 0&&place.second < 15)) {
            cout << cost<< endl;
            return;
        }
        if (!(place.first >= 0&&place.first < 19&&place.second >= 0&&place.second < 15)) {
            continue;
        }
        REP(i, batu.size()) {
            if ((1 << i) & black) {
                grid[batu[i].first][batu[i].second] = 0;
            }
            else {
                grid[batu[i].first][batu[i].second] = i + 1;
            }
        }
        int dx[8] = { 1,1,1,0,0,-1,-1,-1 };
        int dy[8] = { 1,0,-1,1,-1,1,0,-1 };
        REP(q, 8) {
            int color = black;
            for (int j = 1;; ++j) {
                int x = dx[q] * j + place.first;
                int y = dy[q] * j + place.second;
                if ((!(x >= 0 && x < 19 && y >= 0 && y < 15)) || (grid[x][y] == 0)) {
                    if (j == 1) break;
                    next.push(make_pair(mp(x, y), mp(color, cost + 1)));
                    break;
                }
                color += (1 << (grid[x][y] - 1));
            }
        }
    }
    cout << -1 << endl;
}
#undef int
int main() {
    init();
    solve();
}
accuracy: 1
time_ms: 490
memory_kb: 43912
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;

template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}


bool solve(){

    const int h = 19, w = 15;
    vector<string> s(h);
    for(int i = 0; i < h; ++i)
        cin >> s[i];
    vector<vector<char>> v(h, vector<char>(w, -1));
    int st = 0, en = 0;
    int cnt = 0;
    for(int i = 0; i < h; ++i)
        for(int j = 0; j < w; ++j){
            if(s[i][j] == 'O')
                st = i, en = j;
            if(s[i][j] == 'X'){
                v[i][j] = cnt++;
            }
        }

    vector<int> dx{-1, 0, 1, 1, 1, 0, -1, -1};
    vector<int> dy{1, 1, 1, 0, -1, -1, -1, 0};

    vector<map<pair<int,int>, int>> dp(1 << cnt);
    char ans = 100;
    dp[0][make_pair(st, en)] = 0;
    for(int mask = 0; mask < (1 << cnt); ++mask){
        for(auto& p : dp[mask]){
            int i, j;
            tie(i, j) = p.first;
            int val = p.second;
            for(int d = 0; d < 8; ++d){
                int ma = 0;
                bool fl = true;
                int dist = 1;
                int nx, ny;
                for(;; ++dist){
                    nx = i + dist * dx[d];
                    ny = j + dist * dy[d];
                    if(nx >= h)
                        break;
                    if(nx < 0 || ny < 0 || ny >= w){
                        fl = false;
                        break;
                    }
                    if(v[nx][ny] == -1 || mask & (1 << v[nx][ny]))
                        break;
                    ma |= (1 << v[nx][ny]);
                }
                if(!fl || dist == 1)
                    continue;
                if(nx >= h - 1){
                    chmin(ans, char(val + 1));
                    continue;
                }
                if(dp[mask | ma].find(make_pair(nx, ny)) == dp[mask | ma].end() || dp[mask | ma][make_pair(nx, ny)] > char(val + 1)){
                    dp[mask | ma][make_pair(nx, ny)] = char(val + 1);
                }
            }
        }
    }
    cout << (ans == 100 ? -1 : ans) << endl;

    return false;
}

signed main(){
    while(solve());
}
accuracy: 1
time_ms: 30
memory_kb: 57232
final_rank: 15

code_snippet: #include<iostream>
#include<string>
#include<queue>
#include<map>
using namespace std;
int dx[8]={0,1,0,-1,1,1,-1,-1};
int dy[8]={1,0,-1,0,1,-1,1,-1};
main()
{
	map<string,int>M;
	queue<string>P;
	string start="";
	for(int i=0;i<19;i++)
	{
		string s;cin>>s;
		start+=s;
	}
	M[start]=0;
	P.push(start);
	while(!P.empty())
	{
		string now=P.front();P.pop();
		int cost=M[now];
		int nx,ny;
		for(int i=0;i<now.size();i++)
		{
			if(now[i]=='O')
			{
				nx=i/15;
				ny=i%15;
				break;
			}
		}
		for(int r=0;r<8;r++)
		{
			int tx=nx+dx[r],ty=ny+dy[r];
			if(tx<0||ty<0||tx>=19||ty>=15||now[tx*15+ty]!='X')continue;
			string nxt=now;
			while(0<=tx&&tx<19&&0<=ty&&ty<15&&nxt[tx*15+ty]=='X')
			{
				nxt[tx*15+ty]='.';
				tx+=dx[r];
				ty+=dy[r];
			}
			if(tx>=19||tx==18&&0<=ty&&ty<15)
			{
				cout<<cost+1<<endl;
				return 0;
			}
			else if(0<=tx&&tx<19&&0<=ty&&ty<15)
			{
				nxt[nx*15+ny]='.';
				nxt[tx*15+ty]='O';
				if(M.find(nxt)==M.end())
				{
					M[nxt]=cost+1;
					P.push(nxt);
				}
			}
		}
	}
	cout<<-1<<endl;
}
accuracy: 1
time_ms: 180
memory_kb: 34812
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define inf (long long)1e9
using namespace std;

struct data {
  int x, y;
};
bool operator<(const data &l, const data &r) {
  if(l.x != r.x) return l.x < r.x;
  return l.y < r.y;
}

struct cod {
  int s, b, d, c;
};

int x[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
int y[8] = {-1, -1, -1, 0, 1, 1, 1, 0};

int n;
vector<string> s;
vector<data> v;
vector<bool> ch;
map<data, int> mp;

long long solve();
bool isvalid(data now) {
  return now.x >= 0 && now.x < 19 && now.y >= 0 &&
         now.y < 15;
}

int main() {
  s.resize(19);
  for(int i = 0; i < 19; ++i) cin >> s[i];
  for(int i = 0; i < 19; ++i)
    for(int j = 0; j < 15; ++j)
      if(s[i][j] == 'X') {
        mp[{i, j}] = v.size();
        v.push_back({i, j});
      }
  n = v.size();
  cout << solve() << endl;
  return 0;
}

long long solve() {
  queue<cod> qu;
  ch.assign((1 << n), 0);
  for(int i = 0; i < n; ++i)
    for(int j = 0; j < 8; ++j) {
      data now = v[i];
      now.x += x[j];
      now.y += y[j];
      if(!isvalid(now)) continue;
      if(s[now.x][now.y] == 'O' && !(ch[(1 << n) - 1])) {
        qu.push({(1 << n) - 1, i, j, 0});
        ch[(1 << n) - 1] = 1;
      }
    }
  while(!qu.empty()) {
    cod now = qu.front();
    qu.pop();
    for(int i = 0; i < 8; ++i) {
      bool jumped = 0;
      cod nextc = now;
      ++nextc.c;
      int nowx = v[nextc.b].x + x[nextc.d],
          nowy = v[nextc.b].y + y[nextc.d];
      nextc.d = i;
      while(nowx >= 0 && nowy >= 0 && nowx < 19 &&
            nowy < 15) {
        nowx += x[i];
        nowy += y[i];
        if(!isvalid({nowx, nowy}) ||
           mp.find({nowx, nowy}) == mp.end() ||
           !(nextc.s >> mp[{nowx, nowy}] & 1))
          break;
        nextc.b = mp[{nowx, nowy}];
        nextc.s -= 1 << nextc.b;
        jumped = 1;
      }
      if(!jumped) continue;
      if(nowx == 19 ||
         (nowx == 18 && isvalid({nowx, nowy})))
        return nextc.c;
      if(nowy == 15 || nowy == -1 || nowx == -1) continue;
      if(!ch[nextc.s]) {
        qu.push(nextc);
        ch[nextc.s] = 1;
      }
    }
  }
  return -1;
}
accuracy: 1
time_ms: 10
memory_kb: 3308
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define vi vector<int>
#define vii vector<vi>

#define ll long long
#define vl vector<ll>
#define vll vector<vl>
#define pii pair<int, int>

const ll INF = 1e18;

int h = 19, w = 15;
vector<map<pii, int> > dp;
vi dx = {0, 1, 1, 1, 0, -1, -1, -1}, dy = {-1, -1, 0, 1, 1, 1, 0, -1};

bool in(int x, int a, int b) {
	return a <= x and x < b;
}

int main() {
	int n = 0;
	vii a(h, vi(w, -1));
	pii start;
	rep (i, h) {
		rep (j, w) {
			char c;
			cin >> c;
			if (c == 'O') {
				start = pii(i, j);
			}
			if (c == 'X') {
				a[i][j] = n;
				n++;
			}
		}
	}
	int m = 1 << n;
	dp.resize(m);
	dp[m - 1][start] = 0;

	int ans = 1e9;
	for (int i = m - 1; i >= 0; i--) {
		for (auto itr = dp[i].begin(); itr != dp[i].end(); itr++) {
			int y = itr->first.first, x = itr->first.second;
			int cost = itr->second;
			rep (k, 8) {
				int ny = y + dy[k], nx = x + dx[k];
				vi use;
				bool is_black = false;
				while (in(ny, 0, h) and in(nx, 0, w)) {
					if (a[ny][nx] == -1) break;
					if ((i & (1 << a[ny][nx])) == 0) break;
					is_black = true;
					use.push_back(a[ny][nx]);
					ny += dy[k];
					nx += dx[k];
				}
				if (not is_black) continue;
				if (ny == h or (ny == h - 1 and in(nx, 0, w))) {
					ans = min(ans, cost + 1);
				}
				else if (ny == -1 or not in(nx, 0, w)) {
					continue;
				}
				else {
					int ni = i;
					rep (k, use.size()) {
						ni -= (1 << use[k]);
					}
					if (dp[ni][pii(ny, nx)] == 0) {
						dp[ni][pii(ny, nx)] = cost + 1;
					}
					else {
						dp[ni][pii(ny, nx)] = min(dp[ni][pii(ny, nx)], cost + 1);
					}
				}
			}
		}
	}
	if (ans >= 1e8) {
		cout << -1 << endl;
	}
	else{
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 57296
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define vi vector<int>
#define vii vector<vi>

#define ll long long
#define vl vector<ll>
#define vll vector<vl>
#define pii pair<int, int>

const ll INF = 1e18;

int h = 19, w = 15;
vector<map<pii, int> > dp;
vi dx = {0, 1, 1, 1, 0, -1, -1, -1}, dy = {-1, -1, 0, 1, 1, 1, 0, -1};

bool in(int x, int a, int b) {
	return a <= x and x < b;
}

int main() {
	int n = 0;
	vii a(h, vi(w, -1));
	pii start;
	rep (i, h) {
		rep (j, w) {
			char c;
			cin >> c;
			if (c == 'O') {
				start = pii(i, j);
			}
			if (c == 'X') {
				a[i][j] = n;
				n++;
			}
		}
	}
	int m = 1 << n;
	dp.resize(m);
	dp[m - 1][start] = 0;

	int ans = 1e9;
	for (int i = m - 1; i >= 0; i--) {
		for (auto itr = dp[i].begin(); itr != dp[i].end(); itr++) {
			int y = itr->first.first, x = itr->first.second;
			int cost = itr->second;
			rep (k, 8) {
				int ny = y + dy[k], nx = x + dx[k];
				vi use;
				bool is_black = false;
				while (in(ny, 0, h) and in(nx, 0, w)) {
					if (a[ny][nx] == -1) break;
					if ((i & (1 << a[ny][nx])) == 0) break;
					is_black = true;
					use.push_back(a[ny][nx]);
					ny += dy[k];
					nx += dx[k];
				}
				if (not is_black) continue;
				if (ny == h) {
					ans = min(ans, cost + 1);
				}
				else if (ny == -1 or not in(nx, 0, w)) {
					continue;
				}
				else {
					int ni = i;
					rep (k, use.size()) {
						ni -= (1 << use[k]);
					}
					if (dp[ni][pii(ny, nx)] == 0) {
						dp[ni][pii(ny, nx)] = cost + 1;
					}
					else {
						dp[ni][pii(ny, nx)] = min(dp[ni][pii(ny, nx)], cost + 1);
					}
				}
			}
		}
	}
	if (ans >= 1e8) {
		cout << -1 << endl;
	}
	else{
		cout << ans << endl;
	}
}
accuracy: 0.0967741935483871
time_ms: 20
memory_kb: 52016
final_rank: 20

code_snippet: #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<math.h>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#include<vector>
#include<utility>
#include<set>
#include<map>
#include<stdlib.h>
#include<iomanip>

using namespace std;

#define ll long long
#define ld long double
#define EPS 0.0000000001
#define INF 1e9
#define LINF (ll)INF*INF
#define MOD 1000000007
#define rep(i,n) for(int i=0;i<(n);i++)
#define loop(i,a,n) for(int i=a;i<(n);i++)
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)

#define int ll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
typedef vector<pii> vp;

int gcd(int a, int b){
    if(b==0) return a;
    return gcd(b,a%b);
}
int lcm(int a, int b){
    return a/gcd(a,b)*b;
}

int ans = INF;
int h = 19,w = 15;
int dx[] = {0,1,0,-1,1,1,-1,-1};
int dy[] = {1,0,-1,0,1,-1,1,-1};
vs s(19);

void dfs(int x, int y, int cnt){
    if(cnt > 20)return;
    //cout << x << " " << y << " " << cnt << endl;
    //rep(i,h)cout << s[i]<<endl;
    if(x == h-1){
        ans = min(ans,cnt);
        return;
    }
    rep(i,8){
        int nx = x + dx[i];
        int ny = y + dy[i];
        if(nx < 0 || nx >= h || ny < 0 || ny >= w)continue;
        if(s[nx][ny] != 'X')continue;
        bool c = true;
        while(c && s[nx][ny] == 'X'){
            s[nx][ny] = '.';
            nx += dx[i];
            ny += dy[i];
            if(nx < 0 || nx >= h || ny < 0 || ny >= w){
                if(nx >= h)ans = min(ans, cnt+1);
                c = false;
            }
        }
        if(c)dfs(nx,ny,cnt+1);
        while(nx != x || ny != y){
            nx -= dx[i];
            ny -= dy[i];
            s[nx][ny] = 'X';
        }
        s[x][y] = '.';
    }
}

signed main(void) {
    rep(i,h)cin >> s[i];
    int sx,sy;
    rep(i,h)rep(j,w)if(s[i][j] == 'O'){
        sx = i, sy = j;
        s[i][j] = '.';
    }
    dfs(sx,sy,0);
    if(ans == INF)cout << -1 << endl;
    else cout << ans << endl;
}
accuracy: 1
time_ms: 200
memory_kb: 3220
final_rank: 6

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef long double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
const ld eps = 1e-6;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;

char mp[19][15];

int dx[8] = { 1,1,1,0,-1,-1,-1,0 };
int dy[8] = { 1,0,-1,-1,-1,0,1,1 };

int ans = mod;
void dfs(int x, int y, int k) {
	if (x >= 19||(x==18&&0<=y&&y<15)) {
		ans = min(ans, k);
		return;
	}
	if (x < 0 || y < 0 || y >= 15)return;
	rep(j, 8) {
		int nx = x + dx[j], ny = y + dy[j];
		if (nx < 0 || ny < 0 || nx >= 19 || ny >= 15)continue;
		if (mp[nx][ny] == 'X') {
			vector<P> memo;
			while (true) {
				mp[nx][ny] = '.';
				memo.push_back({ nx,ny });
				nx += dx[j]; ny += dy[j];
				if (nx < 0 || ny < 0 || nx >= 19|| ny >= 15)break;
				if (mp[nx][ny] != 'X')break;
			}
			dfs(nx, ny, k + 1);
			rep(i, memo.size()) {
				mp[memo[i].first][memo[i].second] = 'X';
			}
		}
	}
}

void solve() {
	int sx, sy;
	rep(i, 19) {
		rep(j, 15) {
			cin >> mp[i][j];
			if (mp[i][j] == 'O') {
				sx = i, sy = j;
				mp[i][j] = '.';
			}
		}
	}
	dfs(sx, sy, 0);
	if (ans == mod)ans = -1;
	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	//stop
	return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 3232
final_rank: 8