Problem:
B: サイコロを転がさないで
問題文
$H$ 行 $W$ 列からなるグリッドがあります。以降、グリッド上の $i$ 行目 $j$ 列目のマスを $(i, j)$ のマスと書きます。
グリッドの各マスには、$1$ 以上 $6$ 以下の数字か、あるいは
#
の文字が $1$ つずつ書かれています。
ただし、$i$ と $j$ がともに偶数であるような $(i, j)$ のマスには必ず
#
が書かれています。
あなたは以下の図で表されるようなサイコロを $1$ つ持っています。
最初、あなたはこのサイコロを底面が $6$, 前面が $2$, 右面が $3$ となるように $(1, 1)$ のマスに置きます。
ここで、前面は $(i, j)$ の $i$ が増える方向の面を、右面は $j$ が増える方向の面を指します。
その後、サイコロが置かれているマスに辺で隣接する $4$ マスのいずれかにサイコロを転がす操作を好きな回数繰り返すことができます。
サイコロを転がす際、サイコロは転がす方向に90度回転します。
ただし、サイコロを転がす際には以下の条件を満たしている必要があります。
グリッドの外にサイコロを転がしてはならない
#
が書かれているマスに転がしてはならない
転がした後の状態を考えたときに、サイコロの底面に書かれた数字とそのマスに書かれた数字が一致する
$(1, 1)$ のマスには必ず $6$ が書かれていることが保証されます。
サイコロを転がす操作を繰り返すことで、サイコロを $(1, 1)$ のマスから $(H, W)$ のマスに移動させることができるか判定してください。
制約
$1 \leq H, W \leq 100$
グリッドの各マスには $1$ 以上 $6$ 以下の数字、または
#
が書かれている
$i, j$ がともに偶数となるような $(i, j)$ のマスには必ず
#
が書かれている
$(1, 1)$ には $6$ が書かれていることが保証される
入力
入力は以下の形式で標準入力から与えられる。
$H$ $W$
$s_{11}s_{12} \ldots s_{1W}$
$s_{21}s_{22} \ldots s_{2W}$
$\vdots$
$s_{H1}s_{H2} \ldots s_{HW}$
ここで、$s_{ij}$ は $(i, j)$ のマスにかかれている数字または文字を表す。
すなわち、$s_{ij}$ は $1$ 以上 $6$ 以下の数字であるか、あるいは
#
である。
出力
$(1, 1)$ のマスから $(H, W)$ のマスへサイコロを転がして移動させることができるならば
YES
を、そうでないならば
NO
を 1 行で出力せよ。
入力例 1
3 3
631
4#2
516
出力例 1
YES
$(1, 1), (1, 2), (1, 3), (2, 3), (3, 3)$ の順に転がすことで、到達可能です。
入力例 2
3 3
6#1
##2
516
出力例 2
NO
入力例 3
5 5
61244
2#5#3
14641
5#5#5
63126
出力例 3
YES

Submitted solutions:

code_snippet: // https://onlinejudge.u-aizu.ac.jp/beta/room.html#KUPC2020Spring/problems/B
#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define REP(i, n) FOR(i, 0, n)
#define REPR(i, n) for (int i = n - 1; i >= 0; i--)
#define FOR(i, s, n) for (int i = (s), i##_len = (n); i < i##_len; ++i)
#define ALL(obj) (obj).begin(), (obj).end()
#define ALLR(obj) (obj).rbegin(), (obj).rend()
#define DIV(a, b) ((a - 1) / b + 1)

struct Dice {
    // Left, Right, Front, Back, Down, Up
    int l, r, f, b, d, u;

    // y軸方向にプラス
    void RollN() {
        // ++y;
        int buff = d;
        d = b;
        b = u;
        u = f;
        f = buff;
    }

    // y軸方向にマイナス
    void RollS() {
        //  --y;
        int buff = d;
        d = f;
        f = u;
        u = b;
        b = buff;
    }

    // x軸方向にプラス
    void RollE() {
        // ++x;
        int buff = d;
        d = r;
        r = u;
        u = l;
        l = buff;
    }

    // x軸方向にマイナス
    void RollW() {
        // --x;
        int buff = d;
        d = l;
        l = u;
        u = r;
        r = buff;
    }

    // 90度→方向に回転
    void RollL() {
        // ----->
        int buff = f;
        f = l;
        l = b;
        b = r;
        r = buff;
    }

    // 90度←方向に回転
    void RollR() {
        // <------
        int buff = f;
        f = r;
        r = b;
        b = l;
        l = buff;
    }
};

struct dir {
    int y, x;
    char c;
    Dice dice;
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int H, W;
    cin >> H >> W;
    vector<string> v(H);
    for (auto &x : v) {
        cin >> x;
    }
    auto dice = Dice();
    dice.u = 1;
    dice.f = 2;
    dice.r = 3;
    dice.l = 4;
    dice.b = 5;
    dice.d = 6;

    // Y座標、X座標
    queue<dir> q;
    q.push({0, 0, ' ', dice});
    int cnt = 0;
    while (!q.empty()) {
        auto t = q.front();
        q.pop();
        if (t.y == H - 1 && t.x == W - 1) {
            cout << "YES\n";
            return 0;
        }
        if (++cnt > H * W * 100) {
            break;
        }
        if (t.y < H - 1 && t.c != 'n') {
            auto u = t.dice;
            u.RollS();
            if (u.d == v[t.y + 1][t.x] - '0') {
                q.push({t.y + 1, t.x, 's', u});
            }
        }
        if (t.y > 0 && t.c != 's') {
            auto u = t.dice;
            u.RollN();
            if (u.d == v[t.y - 1][t.x] - '0') {
                q.push({t.y - 1, t.x, 'n', u});
            }
        }
        if (t.x < W - 1 && t.c != 'w') {
            auto u = t.dice;
            u.RollE();
            if (u.d == v[t.y][t.x + 1] - '0') {
                q.push({t.y, t.x + 1, 'e', u});
            }
        }
        if (t.x > 0 && t.c != 'e') {
            auto u = t.dice;
            u.RollW();
            if (u.d == v[t.y][t.x - 1] - '0') {
                q.push({t.y, t.x - 1, 'w', u});
            }
        }
    }
    cout << "NO\n";

    return 0;
}
accuracy: 0.4634146341463415
time_ms: 20
memory_kb: 28912
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int mod=1000000007,MAX=105,INF=1<<30;

struct data{
    int h;
    int w;
    int d;
    int f;
    int r;
};

bool can[MAX][MAX][7][7][7];
vector<data> G[MAX][MAX][7][7][7];

int S[MAX][MAX];
int H,W;

void DFS(data u,data p){
    for(data to:G[u.h][u.w][u.d][u.f][u.r]){
        if(to.h==p.h&&to.w==p.w&&to.d==p.d&&to.f==p.f&&to.r==p.r) continue;
        
        if(to.h<0||to.h>=H||to.w<0||to.w>=W) continue;
        
        if(to.d!=S[to.h][to.w]) continue;
        
        if(can[to.h][to.w][to.d][to.f][to.r]) continue;
        
        can[to.h][to.w][to.d][to.f][to.r]=1;
        DFS(to,u);
    }
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    cin>>H>>W;
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            char c;cin>>c;
            if(c=='#') S[i][j]=0;
            else S[i][j]=c-'0';
        }
    }
    
    can[0][0][6][2][3]=1;
    
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            for(int d=1;d<=6;d++){
                for(int f=1;f<=6;f++){
                    for(int r=1;r<=6;r++){
                        if(d==f) continue;
                        if(d==r) continue;
                        if(f==r) continue;
                        
                        G[i][j][d][f][r].push_back({i+1,j,f,7-d,r});
                        G[i][j][d][f][r].push_back({i,j+1,r,f,7-d});
                        G[i][j][d][f][r].push_back({i-1,j,7-f,d,r});
                        G[i][j][d][f][r].push_back({i,j-1,7-r,f,d});
                    }
                }
            }
        }
    }
    
    DFS({0,0,6,2,3},{-1,-1,-1,-1,-1});
    
    bool ok=false;
    
    for(int f=1;f<=6;f++){
        for(int r=1;r<=6;r++){
            if(can[H-1][W-1][S[H-1][W-1]][f][r]) ok=true;
        }
    }
    
    if(ok) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}
accuracy: 1
time_ms: 170
memory_kb: 206220
final_rank: 6

code_snippet: #include <iostream>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <deque>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <map>
#include <stack>
#include <queue>
#include <functional>
#include <climits>
#include <bitset>
#include <random>
#include <tuple>
#include <initializer_list>
#include <fstream>
struct Dice {
	int top, front, right_face;
	int bottom_face() const { return 7 - top; }
	Dice right() const {
		return Dice{ 7 - right_face, front, top };
	}
	Dice left() const {
		return Dice{ right_face, front, 7 - top };
	}
	Dice up() const {
		return Dice{ front, 7 - top, right_face };
	}
	Dice down() const {
		return Dice{ 7 - front, top, right_face };
	}
};
struct Coordinate {
	int i, j;
	Coordinate right() const {
		return Coordinate{ i, j + 1 };
	}
	Coordinate left() const {
		return Coordinate{ i, j - 1 };
	}
	Coordinate up() const {
		return Coordinate{ i - 1, j };
	}
	Coordinate down() const {
		return Coordinate{ i + 1, j };
	}
};
std::vector<std::pair<Coordinate, Dice>> neighbors(const std::pair<Coordinate, Dice> pair) {
	return std::vector<std::pair<Coordinate, Dice>> {std::make_pair(pair.first.right(), pair.second.right()), std::make_pair(pair.first.left(), pair.second.left()), std::make_pair(pair.first.up(), pair.second.up()), std::make_pair(pair.first.down(), pair.second.down())};
}
int main() {
	int height, width; std::cin >> height >> width;
	std::vector<std::string> state(height); for (auto& line : state) std::cin >> line;
	std::vector<std::vector<std::vector<std::vector<std::vector<bool>>>>> memo(height, std::vector<std::vector<std::vector<std::vector<bool>>>>(width, std::vector<std::vector<std::vector<bool>>>(6, std::vector<std::vector<bool>>(6, std::vector<bool>(6, false)))));
	std::stack<std::pair<Coordinate, Dice>> stack;
	memo[0][0][0][1][2] = true;
	stack.emplace(Coordinate{ 0, 0 }, Dice{ 1, 2, 3 });
	while (!stack.empty()) {
		const auto top = stack.top(); stack.pop();
		for (const auto next : neighbors(top)) {
			if (0 > next.first.i || 0 > next.first.j || height <= next.first.i || width <= next.first.j) continue;
			if (memo[next.first.i][next.first.j][next.second.top - 1][next.second.front - 1][next.second.right_face - 1]) continue;
			if (state[next.first.i][next.first.j] - '0' == next.second.bottom_face()) {
				memo[next.first.i][next.first.j][next.second.top - 1][next.second.front - 1][next.second.right_face - 1] = true;
				stack.push(next);
			}
		}
	}
	bool can_reach = false;
	for (auto t = 0; t < 6; ++t) for (auto f = 0; f < 6; ++f) for (auto r = 0; r < 6; ++r) if (memo.back().back()[t][f][r]) can_reach = true;
	std::cout << (can_reach ? "YES" : "NO") << std::endl;
}
accuracy: 1
time_ms: 20
memory_kb: 31004
final_rank: 3

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>

#define rep(i, m, n) for(int i=int(m);i<int(n);i++)
#define all(c) begin(c),end(c)

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; }

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
using Int = long long int;
using Double = long double;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x)  cerr << #x << " = " << (x) << endl
#define MOD 1000000007


struct BFS01 {
    struct edge {
        ll to, cost;
    };
    typedef pair<ll, ll> P;//firstは最短距離、secondは頂点の番号

    int V;//超点数
    vector<vector<edge> > G;//グラフ,G[i]はiから出る辺の集合,G[i][j]はiから出る辺のj番目の辺
    vector<ll> d; //最短距離

    BFS01(int N) {
        V = N;
        G.resize(N);
        d = vector<ll>(N);
    };

    void addEdge(int from, int to, int cost) {
        edge e;
        e.to = to;
        e.cost = cost;
        G[from].push_back(e);
    }

    void calc(int s) {
//        priority_queue<P,vector<P>,greater<P> > que;
        deque<P> que;
        fill(d.begin(), d.end(), INFl);
        d[s] = 0;
        que.push_back(P(0, s));

        while (!que.empty()) {
            P p = que.front();
            que.pop_front();
            ll v = p.second;
            if (d[v] < p.first) continue;
            for (int i = 0; i < G[v].size(); i++) {
                edge e = G[v][i];
                if (d[e.to] > d[v] + e.cost && !(d[e.to] == INFl && d[v] == INFl)) {
                    d[e.to] = d[v] + e.cost;
                    if (e.cost == 0) {
                        que.push_front(P(d[e.to], e.to));
                    } else {
                        que.push_back(P(d[e.to], e.to));
                    }
                }
            }
        }

    }
};


//edit
const int TOP = 0;
const int FRONT = 1;
const int RIGHT = 2;
const int LEFT = 3;
const int BACK = 4;
const int BOTTOM = 5;
vector<vector<Int>> rot(720, vector<Int>(6));
vector<vector<Int>> dices;

vector<Int> hash_d(Int hash) {
    vector<Int> rest = {1, 2, 3, 4, 5, 6};
    vector<Int> ret;
    Int base = 120;

    for (int i = 0; i < 6; ++i) {
//        ret.push_back(1 + hash / base);
        ret.push_back(rest[hash / base]);
        rest.erase(rest.begin() + hash / base);


        hash %= base;
        if ((5 - i) > 0) {
            base /= 5 - i;
        }
    }

    return ret;
}

Int fact(Int n) {
    if (n > 0) return fact(n - 1) * n;
    return 1;
}

Int d_hash(vector<Int> d) {
    if (d.size() == 1) {
        return 0;
    }
    //今ある数字が何番目に小さいか
    Int cnt = 0;
    Int base = fact(static_cast<Int>(d.size()) - 1);

    for (auto e : d) {
        if (e < d[0]) cnt++;
    }
    Int ret = cnt * base;
    d.erase(d.begin());
    ret += d_hash(d);

    return ret;
//    Int ret = 0;
//    Int base = 1;
//    for (int i = 0; i < 6; ++i) {
//        Int tmp = base * (d[5 - i] - 1);
//        ret += tmp;
//
//        base *= (i + 1);
//    }
//
//    return ret;
}

Int rot_any(Int hash, vector<Int> dir) {
    vector<Int> dice = hash_d(hash);
    vector<Int> val;
    for (auto e : dir) val.push_back(dice[e]);
    rotate(val.begin(), val.begin() + 1, val.end());
    vector<Int> new_dice = dice;

//    for (int i = 0, ii = 0; i < 6; ++i) {
//        if (ii < 4 && i == dir[ii]) {
//            new_dice[i] = val[dir[ii]];
//            ii++;
//        }
//    }

    for (int i = 0; i < 4; ++i) {
        int j = (i + 1) % 4;

        new_dice[dir[i]] = dice[dir[j]];
    }

    return d_hash(new_dice);
}

Int rot_R(Int hash) {
//    vector<Int> dice = hash_d(hash);
    vector<Int> dir = {TOP, LEFT, BOTTOM, RIGHT};
//    vector<Int> val;
//    for (auto e : idx) val.push_back(dice[e]);
//    rotate(val.begin(), val.begin() + 1, val.end());
//    vector<Int> new_dice = dice;
//
//    for (int i = 0, ii = 0; i < 6; ++i) {
//        if (ii < 4 && i == idx[ii]) {
//            new_dice[i] = idx[ii];
//            ii++;
//        }
//    }
//
//    return d_hash(new_dice);

    return rot_any(hash, dir);
}

Int rot_L(Int hash) {
    vector<Int> dir = {TOP, RIGHT, BOTTOM, LEFT};
    return rot_any(hash, dir);
}

Int rot_F(Int hash) {
    vector<Int> dir = {TOP, BACK, BOTTOM, FRONT};
    return rot_any(hash, dir);
}

Int rot_B(Int hash) {
    vector<Int> dir = {TOP, FRONT, BOTTOM, BACK};
    return rot_any(hash, dir);
}

void print_vec(vector<Int> v) {
    for (auto e : v) cout << e << " ";
    cout << endl;
}

class Solve {
public:
    void init() {
        vector<Int> dice = {1, 2, 3, 4, 5, 6};
        do {
            Int hash = d_hash(dice);
            rot[hash][RIGHT] = rot_R(hash);
            rot[hash][LEFT] = rot_L(hash);
            rot[hash][FRONT] = rot_F(hash);
            rot[hash][BACK] = rot_B(hash);
            dices.push_back(dice);
        } while (next_permutation(all(dice)));


    }

    void solve() {
        init();

        Int H, W;
        cin >> H >> W;

        vector<string> S(H);
        for (int i = 0; i < H; ++i) cin >> S[i];

        auto get_cell = [&](Int hash, Int h, Int w) -> Int {
            return w + (W * h) + (W * H * hash);
        };

        auto i_get_cell = [&](Int tapu) {
            Int w = tapu % W;
            Int h = ((tapu - w) / W) % H;
            Int hash = (tapu - w - W * h) / (W * H);
            return make_tuple(hash, h, w);
        };


//        BFS01 neri(W * H * 720);
        queue<Int> que;
        vector<vector<vector<bool>>> tapi(720, vector<vector<bool>>(H, vector<bool>(W, false)));
        tapi[0][0][0] = true;
        que.push(get_cell(0, 0, 0));

        while (!que.empty()) {
            Int val = que.front();
            que.pop();
            Int h, w, hash;
            tie(hash, h, w) = i_get_cell(val);

            vector<Int> dh = {0, 1, 0, -1};
            vector<Int> dw = {1, 0, -1, 0};
            for (int k = 0; k < 4; ++k) {
                Int nh = h + dh[k];
                Int nw = w + dw[k];
                if (!(nh >= 0 && nh < H && nw >= 0 && nw < W)) continue;

                vector<Int> next_dice;
                if (k == 0) {
                    //右へ転がす
//                            next_dice = hash_d(rot_R(hash));
//                            next_dice = hash_d(rot[hash][RIGHT]);
                    next_dice = dices[rot[hash][RIGHT]];
                } else if (k == 1) {
//                            next_dice = hash_d(rot[hash][FRONT]);
                    next_dice = dices[rot[hash][FRONT]];
                } else if (k == 2) {
//                            next_dice = hash_d(rot[hash][LEFT]);
                    next_dice = dices[rot[hash][LEFT]];
                } else {
//                            next_dice = hash_d(rot[hash][BACK]);
                    next_dice = dices[rot[hash][BACK]];
                }

                Int next_hash = d_hash(next_dice);

                //底面が条件に合わなければ飛ばす
                if (next_dice[BOTTOM] + '0' != S[h + dh[k]][w + dw[k]]) {
                    continue;
                }

//                        neri[get_cell(h,w,hash)][]
//                neri.addEdge(get_cell(hash, h, w), get_cell(next_hash, nh, nw), 1);
                if (!tapi[next_hash][nh][nw]) {
                    tapi[next_hash][nh][nw] = true;
                    que.push(get_cell(next_hash, nh, nw));
                }
            }
        }

//        for (int h = 0; h < H; ++h) {
//            for (int w = 0; w < W; ++w) {
//                for (int hash = 0; hash < 720; ++hash) {
//                    //底面がS[h][w]となるものをすべて転がす
////                    if (h == 1 && w == 0 && hash == 489) {
////                        int ei = 13 + 33;
////                    }
//
//                    vector<Int> dice = hash_d(hash);
//
//                    //底面が条件に合わなければ飛ばす
//                    if (dice[BOTTOM] + '0' != S[h][w]) continue;
//
//                    vector<Int> dh = {0, 1, 0, -1};
//                    vector<Int> dw = {1, 0, -1, 0};
//
//                    for (int k = 0; k < 4; ++k) {
//                        Int nh = h + dh[k];
//                        Int nw = w + dw[k];
//                        if (!(nh >= 0 && nh < H && nw >= 0 && nw < W)) continue;
//
//                        vector<Int> next_dice;
//                        if (k == 0) {
//                            //右へ転がす
////                            next_dice = hash_d(rot_R(hash));
////                            next_dice = hash_d(rot[hash][RIGHT]);
//                            next_dice = dices[rot[hash][RIGHT]];
//                        } else if (k == 1) {
////                            next_dice = hash_d(rot[hash][FRONT]);
//                            next_dice = dices[rot[hash][FRONT]];
//                        } else if (k == 2) {
////                            next_dice = hash_d(rot[hash][LEFT]);
//                            next_dice = dices[rot[hash][LEFT]];
//                        } else {
////                            next_dice = hash_d(rot[hash][BACK]);
//                            next_dice = dices[rot[hash][BACK]];
//                        }
//
//                        Int next_hash = d_hash(next_dice);
//
//                        //底面が条件に合わなければ飛ばす
//                        if (next_dice[BOTTOM] + '0' != S[h + dh[k]][w + dw[k]]) {
//                            continue;
//                        }
//
////                        neri[get_cell(h,w,hash)][]
//                        neri.addEdge(get_cell(hash, h, w), get_cell(next_hash, nh, nw), 1);
//                    }
//                }
//            }
//        }

//        neri.calc(get_cell(0, 0, 0));

//        if (!true) {
//            while (true) {
//                Int tmp = 0;
//                cin >> tmp;
//                if (tmp == -1) break;
//
//                for (auto e : neri.G[tmp]) {
//                    Int tapu = e.to;
//                    Int w = tapu % W;
//                    Int h = ((tapu - w) / W) % H;
//                    Int hash = (tapu - w - W * h) / (W * H);
//                    cout << e.to << endl;
//                    cout << hash << " " << w << " " << h << endl;
//                }
//            }
//        }

        for (int i = 0; i < 720; ++i) {
//            if (neri.d[get_cell(i, H - 1, W - 1)] != INFl) {
            if (tapi[i][H - 1][W - 1]) {

                cout << "YES" << endl;
                return;
            }
        }


        cout << "NO" << endl;
    }

};


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

    Solve().solve();


    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 8432
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint     = long long;
const lint inf = 1LL << 60;
const lint mod = 1000000007;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int h, w;
    cin >> h >> w;
    vector<string> s(h);
    for (int i = 0; i < h; ++i) {
        cin >> s[i];
    }
    vector<vector<vector<vector<vector<int>>>>> visited(
        h, vector<vector<vector<vector<int>>>>(
               w, vector<vector<vector<int>>>(6, vector<vector<int>>(6, vector<int>(6, 0))))); // bottom, right,
    struct state {
        int i, j, k, l, m;
    };
    queue<state> q;
    q.push({0, 0, 5, 2, 1});
    visited[0][0][5][2][1] = 1;
    while (!q.empty()) {
        auto c = q.front();
        q.pop();
        if (c.i == h - 1 && c.j == w - 1) {
            cout << "YES"
                 << "\n";
            return 0;
        }
        // up
        if (c.i != 0) {
            int nk    = 5 - c.m;
            int nl    = c.l;
            int nm    = c.k;
            state nxt = {c.i - 1, c.j, nk, nl, nm};
            if (s[c.i - 1][c.j] - '1' == nk)
                if (visited[nxt.i][nxt.j][nxt.k][nxt.l][nxt.m] == 0) {
                    visited[nxt.i][nxt.j][nxt.k][nxt.l][nxt.m] = 1;
                    q.push(nxt);
                }
        }
        // right
        if (c.j != w - 1) {
            int nk    = c.l;
            int nl    = 5 - c.k;
            int nm    = c.m;
            state nxt = {c.i, c.j + 1, nk, nl, nm};
            if (s[c.i][c.j + 1] - '1' == nk)
                if (visited[nxt.i][nxt.j][nxt.k][nxt.l][nxt.m] == 0) {
                    visited[nxt.i][nxt.j][nxt.k][nxt.l][nxt.m] = 1;
                    q.push(nxt);
                }
        }
        // left
        if (c.j != 0) {
            int nk    = 5 - c.l;
            int nl    = c.k;
            int nm    = c.m;
            state nxt = {c.i, c.j - 1, nk, nl, nm};
            if (s[c.i][c.j - 1] - '1' == nk)
                if (visited[nxt.i][nxt.j][nxt.k][nxt.l][nxt.m] == 0) {
                    visited[nxt.i][nxt.j][nxt.k][nxt.l][nxt.m] = 1;
                    q.push(nxt);
                }
        }
        // down
        if (c.i != h - 1) {
            int nk    = c.m;
            int nl    = c.l;
            int nm    = 5 - c.k;
            state nxt = {c.i + 1, c.j, nk, nl, nm};
            if (s[c.i + 1][c.j] - '1' == nk)
                if (visited[nxt.i][nxt.j][nxt.k][nxt.l][nxt.m] == 0) {
                    visited[nxt.i][nxt.j][nxt.k][nxt.l][nxt.m] = 1;
                    q.push(nxt);
                }
        }
    }
    cout << "NO"
         << "\n";
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 25432
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint     = long long;
const lint inf = 1LL << 60;
const lint mod = 1000000007;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int h, w;
    cin >> h >> w;
    vector<string> s(h);
    for (int i = 0; i < h; ++i) {
        cin >> s[i];
    }
    vector<vector<vector<vector<vector<int>>>>> dp(
        h, vector<vector<vector<vector<int>>>>(
               w, vector<vector<vector<int>>>(6, vector<vector<int>>(6, vector<int>(6, -1))))); // bottom, right, front
    dp[0][0][5][2][1] = 1;

    function<int(int, int, int, int, int, int)> dfs = [&](int i, int j, int k, int l, int m, int from) {
        if (s[i][j] == '#' || s[i][j] - '1' != k)
            return dp[i][j][k][l][m] = 0;
        if (dp[i][j][k][l][m] != -1)
            return dp[i][j][k][l][m];
        bool ok = 0;
        // up
        if (i != 0 && from != 3) {
            int nk = 5 - m;
            int nl = l;
            int nm = k;
            ok |= dfs(i - 1, j, nk, nl, nm, 0);
        }
        // right
        if (j != w - 1 && from != 2) {
            int nk = l;
            int nl = 5 - k;
            int nm = m;
            ok |= dfs(i, j + 1, nk, nl, nm, 1);
        }
        // left
        if (j != 0 && from != 1) {
            int nk = 5 - l;
            int nl = k;
            int nm = m;
            ok |= dfs(i, j - 1, nk, nl, nm, 2);
        }
        // down
        if (i != h - 1 && from != 0) {
            int nk = m;
            int nl = l;
            int nm = 5 - k;
            ok |= dfs(i + 1, j, nk, nl, nm, 3);
        }
        return dp[i][j][k][l][m] = ok;
    };
    bool anyok = 0;
    for (int i = 0; i < 6; ++i) {
        for (int j = 0; j < 6; ++j) {
            for (int k = 0; k < 6; ++k) {
                if (i + j == 5 || j + k == 5 || k + i == 5)
                    continue;
                anyok |= dfs(h - 1, w - 1, i, j, k, -1);
            }
        }
    }
    if (anyok)
        cout << "YES"
             << "\n";
    else
        cout << "NO"
             << "\n";
    return 0;
}
accuracy: 0.4146341463414634
time_ms: 10
memory_kb: 25368
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define get_unique(x) x.erase(unique(all(x)), x.end());
typedef long long ll;
typedef complex<double> Complex;
const int INF = 1e9;
const ll MOD = 1e9 + 7;
const ll LINF = 1e18;
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 (b < a) {
        a = b;
        return 1;
    }
    return 0;
}
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...));
}
struct DICE {
    int L, R, U, D, B, F;
    void right() {
        int x;
        x = R;
        R = U;
        U = L;
        L = D;
        D = x;
    }
    void left() {
        int x;
        x = L;
        L = U;
        U = R;
        R = D;
        D = x;
    }
    void down() {
        int x;
        x = F;
        F = U;
        U = B;
        B = D;
        D = x;
    }
    void up() {
        int x;
        x = B;
        B = U;
        U = F;
        F = D;
        D = x;
    }
};
int main() {
    int h, w;
    cin >> h >> w;
    auto v = make_vec<int>(h, w);
    rep(i, h) rep(j, w) {
        char c;
        cin >> c;
        if (c == '#')
            v[i][j] = -1;
        else
            v[i][j] = c - '0';
    }

    auto d = make_vec<DICE>(h, w);
    auto dp = make_vec<int>(h, w);

    d[0][0] = {4, 3, 1, 6, 5, 2};
    dp[0][0] = 1;
    rep(_, 1000) {
        rep(i, h) {
            rep(j, w) {
                if (j + 1 < w && v[i][j + 1] != -1) {
                    d[i][j].right();
                    if (d[i][j].D == v[i][j + 1]) {
                        d[i][j + 1] = d[i][j];
                        dp[i][j + 1] |= dp[i][j];
                    }
                    d[i][j].left();
                }
                if (i + 1 < h && v[i + 1][j] != -1) {
                    d[i][j].down();
                    if (d[i][j].D == v[i + 1][j]) {
                        d[i + 1][j] = d[i][j];
                        dp[i + 1][j] |= dp[i][j];
                    }
                    d[i][j].up();
                }
                if (j - 1 >= 0 && v[i][j - 1] != -1 && dp[i][j] == 1 &&
                    dp[i][j - 1] == 0) {
                    d[i][j].left();
                    if (d[i][j].D == v[i][j - 1]) {
                        d[i][j - 1] = d[i][j];
                        dp[i][j - 1] |= dp[i][j];
                    }
                    d[i][j].right();
                }
                if (i - 1 >= 0 && v[i - 1][j] != -1 && dp[i][j] == 1 &&
                    dp[i - 1][j] == 0) {
                    d[i][j].up();
                    if (d[i][j].D == v[i - 1][j]) {
                        d[i - 1][j] = d[i][j];
                        dp[i - 1][j] |= dp[i][j];
                    }
                    d[i][j].down();
                }
            }
        }
    }
    /*
    cout << endl;
    rep(i, h) {
        rep(j, w) cout << d[i][j].D;
        cout << endl;
    }
    */
    cout << (dp[h - 1][w - 1] ? "YES" : "NO") << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 3288
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint     = long long;
const lint inf = 1LL << 60;
const lint mod = 1000000007;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int h, w;
    cin >> h >> w;
    vector<string> s(h);
    for (int i = 0; i < h; ++i) {
        cin >> s[i];
    }
    vector<vector<vector<vector<vector<int>>>>> dp(
        h, vector<vector<vector<vector<int>>>>(
               w, vector<vector<vector<int>>>(6, vector<vector<int>>(6, vector<int>(6, -1))))); // bottom, right, front
    dp[0][0][5][2][1] = 1;

    function<int(int, int, int, int, int, int)> dfs = [&](int i, int j, int k, int l, int m, int from) {
        if (s[i][j] == '#' || s[i][j] - '1' != k)
            return dp[i][j][k][l][m] = 0;
        if (dp[i][j][k][l][m] != -1)
            return dp[i][j][k][l][m];
        bool ok = 0;
        // up
        if (i != 0 && from != 3) {
            int nk = 5 - m;
            int nl = l;
            int nm = k;
            ok |= dfs(i - 1, j, nk, nl, nm, 0);
        }
        // right
        if (j != w - 1 && from != 2) {
            int nk = l;
            int nl = 5 - k;
            int nm = m;
            ok |= dfs(i, j + 1, nk, nl, nm, 1);
        }
        // left
        if (j != 0 && from != 1) {
            int nk = 5 - l;
            int nl = k;
            int nm = m;
            ok |= dfs(i, j - 1, nk, nl, nm, 2);
        }
        // down
        if (i != h - 1 && from != 0) {
            int nk = m;
            int nl = l;
            int nm = 5 - k;
            ok |= dfs(i + 1, j, nk, nl, nm, 3);
        }
        return dp[i][j][k][l][m] = ok;
    };
    bool anyok = 0;
    for (int i = 0; i < 6; ++i) {
        for (int j = 0; j < 6; ++j) {
            for (int k = 0; k < 6; ++k) {
                anyok |= dfs(h - 1, w - 1, i, j, k, -1);
            }
        }
    }
    if (anyok)
        cout << "YES"
             << "\n";
    else
        cout << "NO"
             << "\n";
    return 0;
}
accuracy: 0.4146341463414634
time_ms: 10
memory_kb: 25368
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int mod=1000000007,MAX=105,INF=1<<30;

struct data{
    int h;
    int w;
    int d;
    int f;
    int r;
};

bool can[MAX][MAX][7][7][7];
vector<data> G[MAX][MAX][7][7][7];

int S[MAX][MAX];
int H,W;

void DFS(data u,data p){
    for(data to:G[u.h][u.w][u.d][u.f][u.r]){
        if(to.h==p.h&&to.w==p.w&&to.d==p.d&&to.f==p.f&&to.r==p.r) continue;
        
        if(to.h<0||to.h>=H||to.w<0||to.w>=W) continue;
        
        if(to.d!=S[to.h][to.w]) continue;
        
        if(can[to.h][to.w][to.d][to.f][to.r]) continue;
        
        can[to.h][to.w][to.d][to.f][to.r]=1;
        DFS(to,u);
    }
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    cin>>H>>W;
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            char c;cin>>c;
            if(c=='#') S[i][j]=0;
            else S[i][j]=c-'0';
        }
    }
    
    can[0][0][6][2][3]=1;
    
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            for(int d=1;d<=6;d++){
                for(int f=1;f<=6;f++){
                    for(int r=1;r<=6;r++){
                        if(d==f) continue;
                        if(d==r) continue;
                        if(f==r) continue;
                        
                        G[i][j][d][f][r].push_back({i+1,j,f,7-d,r});
                        G[i][j][d][f][r].push_back({i,j+1,r,f,7-d});
                        G[i][j][d][f][r].push_back({i-1,j,7-f,d,r});
                        G[i][j][d][f][r].push_back({i,j-1,7-r,f,d});
                    }
                }
            }
        }
    }
    
    DFS({0,0,6,2,3},{-1,-1,-1,-1,-1});
    
    bool ok=false;
    
    for(int f=1;f<=6;f++){
        for(int r=1;r<=6;r++){
            if(can[H-1][W-1][S[H-1][W-1]][f][r]) ok=true;
        }
    }
    
    if(ok) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}
accuracy: 1
time_ms: 170
memory_kb: 206176
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int mod=1000000007,MAX=105,INF=1<<30;

struct data{
    int h;
    int w;
    int d;
    int f;
    int r;
};

bool can[MAX][MAX][7][7][7];
vector<data> G[MAX][MAX][7][7][7];

int S[MAX][MAX];
int H,W;

void DFS(data u,data p){
    for(data to:G[u.h][u.w][u.d][u.f][u.r]){
        if(to.h==p.h&&to.w==p.w&&to.d==p.d&&to.f==p.f&&to.r==p.r) continue;
        
        if(to.h<0||to.h>=H||to.w<0||to.w>=W) continue;
        
        if(to.d!=S[to.h][to.w]) continue;
        
        can[to.h][to.w][to.d][to.f][to.r]=1;
        DFS(to,u);
    }
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    cin>>H>>W;
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            char c;cin>>c;
            if(c=='#') S[i][j]=0;
            else S[i][j]=c-'0';
        }
    }
    
    can[0][0][6][2][3]=1;
    
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            for(int d=1;d<=6;d++){
                for(int f=1;f<=6;f++){
                    for(int r=1;r<=6;r++){
                        if(d==f) continue;
                        if(d==r) continue;
                        if(f==r) continue;
                        
                        G[i][j][d][f][r].push_back({i+1,j,f,7-d,r});
                        G[i][j][d][f][r].push_back({i,j+1,r,f,7-d});
                        G[i][j][d][f][r].push_back({i-1,j,7-f,d,r});
                        G[i][j][d][f][r].push_back({i,j-1,7-r,f,d});
                    }
                }
            }
        }
    }
    
    DFS({0,0,6,2,3},{-1,-1,-1,-1,-1});
    
    bool ok=false;
    
    for(int f=1;f<=6;f++){
        for(int r=1;r<=6;r++){
            if(can[H-1][W-1][S[H-1][W-1]][f][r]) ok=true;
        }
    }
    
    if(ok) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}
accuracy: 0.1951219512195122
time_ms: 160
memory_kb: 199864
final_rank: 10