Problem:
Problem
「大変！僕が大切にしていたサイコロが虫に食い荒らされてしまっている！」
「大変！サイコロの中に大切な指輪を落としてしまった！」
頑張って取り出そうとサイコロを回してみたけれど、かえって奥にいってしまったみたい . . .
そういえば昔Annazonで買った小型のロボットが押入れにあったような気がするな
--------- 一時間後 ---------
「あった！」
そこには、よく分からない粘菌が付着してネバネバしている正六面体のロボットCUBEくんの姿があった。
「なんかネバネバするけど . . . まぁいいか！ 」
僕はCUBEくんをサイコロの虫に食われた場所に設置した。
虫に食われた立方体のサイコロが $N \times N \times N$ マスの3次元グリッドで与えられる。
ここで、便宜上3次元空間を考え、マスの辺に平行な向きにそれぞれ x 軸と y 軸をとり、サイコロ上面が向く方向を z 軸正方向とする。
サイコロの外側は1箇所を除いて全て壁である。その一箇所にCUBEくんを設置した。CUBEくんの初期位置はサイコロの上面にある。
CUBEくんは始め上向き(z軸正方向)に目がついている。
CUBEくんは毎ターン、以下の中から一つ選び行動する。
前進する
目のついている向きに壁がない場合選択できる。
目のついている向きに１マス移動することができる。
上の条件を満たすのであれば、上方向、下方向であっても移動できることに注意せよ。
目の位置を移動
目の位置を側面(対面と現在の面を除いた4面のいずれか)に移動する。
サイコロの回転
CUBEくんがネバネバして壁にくっついている状態であれば選択できる。
サイコロを側面4方向に転がすように90°回転させることができる。
洗浄
CUBEくんは粘菌を洗浄して一時的にネバネバを弱めることができる。
洗浄したターン、次のターン、その次のターン、これら計3ターンが経過するとネバネバは元どおりになる。
ネバネバが弱まっている間はCUBEくんの下に壁が無い限り落下し続ける。
ネバネバが弱まっている状態で洗浄することはできない。
洗浄回数に制限はない。
何もしない
指輪について
指輪は不思議な力でサイコロ内のいずれかの壁と隣接し、くっついている。
CUBEくんが指輪と同じ場所を通ると、指輪は回収される。落下中に指輪を回収することも可能。
指輪のあるマスは何もないマスと同様に通過できる。
CUBEくんの初期位置に指輪があることはない。
指輪はちょうど1つ存在する。
指輪は必ず回収できる。
落下について
1ターン内に一気に落下する。
CUBEくんがネバネバしている状態で落下するときは、CUBEくんと壁が面で接するまで落下し続ける。
落下によってサイコロの外に飛び出しそうな時は、CUBEくんを設置した位置で止まる。
ターンは以下のように進みます
CUBEくんの行動
CUBEくんの落下処理
ターンを進める
ゴール判定
CUBEくんが指輪を取って設置した位置に戻ってくるまでの最短のターン数を答えよ。
Input
入力は以下の形式で与えられる。
$N$
$A_{1,1,N}$ $\cdots$ $A_{N,1,N}$
$\vdots$
$A_{1,N,N}$ $\cdots$ $A_{N,N,N}$

$A_{1,1,N-1}$ $\cdots$ $A_{N,1,N-1}$
$\vdots$
$A_{1,N,N-1}$ $\cdots$ $A_{N,N,N-1}$

$\vdots$

$A_{1,1,1}$ $\cdots$ $A_{N,1,1}$
$\vdots$
$A_{1,N,1}$ $\cdots$ $A_{N,N,1}$
'.' 何もない空間
'#' 壁
'S' ロボットのスタート位置
'R'  指輪
なお、各面の間には空行が入る
Constraints
入力は以下の条件を満たす。
$3 \leq N \leq 30$
$N$は整数
$A_{x,y,z}$は '.' , '#' , 'S' , 'R' のいずれか
'#'は連結
指輪は壁と隣接した場所にある
'S'と'R'は、それぞれただ一つだけ出現する
$A_{x,y,z}$ = 'S'ならば $1 < x < N$, $1 < y < N$, $z=N$
$z=N$をサイコロの上面, $z=1$をサイコロの底面とする
Output
CUBEくんが指輪を回収して初期位置に戻ってくるまでの最短のターン数を答えよ。
Sample Input 1
3
###
#S#
###

###
#R#
###

###
###
###
Sample Output 1
4
例えば、以下の順番で操作を行うと、計４ターンで指輪を回収しスタート地点に戻ることができます。
洗浄
何もしない
何もしない
前進する
Sample Input 2
5
#####
#####
##S##
#####
#####

#####
#####
##.##
#####
#####

#####
#####
##.##
#####
#####

#####
#...#
#.R.#
#...#
#####

#####
#####
#####
#####
#####
Sample Output 2
6
Sample Input 3
5
#####
#####
##S##
#####
#####

#####
#####
##.R#
#####
#####

#####
#####
#####
#####
#####

#####
#####
#####
#####
#####

#####
#####
#####
#####
#####
Sample Output 3
7

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

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

int INF = 1e9;
//const ll mod = 1000000007;
int N;
string S[35][35];
int dp[35][35][35][2][3][6][6];
//x座標 y座標 z座標 指輪の有無 残ネバネバ サイコロの向き 目の向き
int dx[6] = {1, 0, 0, -1, 0, 0};
int dy[6] = {0, 1, 0, 0, -1, 0};
int dz[6] = {0, 0, 1, 0, 0, -1};
int sx, sy, sz;
struct state;
queue<state> que;
struct state {
    int x, y, z, ring, turn, dice, eye, cost;
    state() {}
    void check() {
        if(chmin(dp[x][y][z][ring][turn][dice][eye], cost)) {
            que.push(*this);
            //cerr << "-> ";
            //print();
        }
    }
    void getring() {
        if(S[x][y][z] == 'R') ring = 1;
    }
    void go() {
        cost++;
        int newx = x + dx[eye];
        int newy = y + dy[eye];
        int newz = z + dz[eye];
        bool canmove = true;
        if(newx < 0 or newx >= N) canmove = false;
        if(newy < 0 or newy >= N) canmove = false;
        if(newz < 0 or newz >= N) canmove = false;
        if(canmove and S[newx][newy][newz] == '#') canmove = false;
        if(canmove) {
            x = newx;
            y = newy;
            z = newz;
        }
        drop();
    }
    void rotateeye(int idx) {
        cost++;
        eye = (eye + idx) % 6;
        drop();
    }
    void rotatedice(int idx) {
        cost++;
        if(turn == 0) dice = (dice + idx) % 6;
        drop();
    }
    void wash() {
        cost++;
        if(turn == 0) turn = 3;
        drop();
    }
    void nothing() {
        cost++;
        drop();
    }
    void drop() {
        while(true) {
            getring();
            int newx = x + dx[dice];
            int newy = y + dy[dice];
            int newz = z + dz[dice];
            bool canmove = true;
            if(turn == 0) {
                for(int k = 0; k < 6; k++) {
                    int nowx = x + dx[k];
                    int nowy = y + dy[k];
                    int nowz = z + dz[k];
                    if(nowx >= 0 and nowx < N and nowy >= 0 and nowy < N and nowz >= 0 and nowz < N and S[nowx][nowy][nowz] == '#') {
                        canmove = false;
                    }
                }
            }
            if(newx < 0 or newx >= N) canmove = false;
            if(newy < 0 or newy >= N) canmove = false;
            if(newy < 0 or newy >= N) canmove = false;
            if(canmove and S[newx][newy][newz] == '#') canmove = false;
            if(!canmove) break;
            x = newx;
            y = newy;
            z = newz;
            getring();
        }
        if(turn >= 1) turn--;
    }
    bool gameclear() {
        if(x != sx) return false;
        if(y != sy) return false;
        if(z != sz) return false;
        if(ring != 1) return false;
        return true;
    }

    void print() {
        cerr << "state: " << x << " " << y << " " << z << " "<< ring << " " << turn << " " << eye << " " << dice << " " << cost << endl;
    }
};

int main() {
    //作問者とお話がしたいな
    cin >> N;
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            cin >> S[i][j];
            for(int k = 0; k < N; k++) {
                if(S[i][j][k] == 'S') {
                    sx = i;
                    sy = j;
                    sz = k;
                }
            }
        }
    }
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            for(int k = 0; k < N; k++) {
                for(int l = 0; l < 2; l++) {
                    for(int m = 0; m < 3; m++) {
                        for(int n = 0; n < 6; n++) {
                            for(int o = 0; o < 6; o++) {
                                dp[i][j][k][l][m][n][o] = INF;
                            }
                        }
                    }
                }
            }
        }
    }
    state initialstate;
    initialstate.x = sx;
    initialstate.y = sy;
    initialstate.z = sz;
    initialstate.ring = 0;
    initialstate.turn = 0;
    initialstate.dice = 0;
    initialstate.eye = 3;
    initialstate.cost = 0;
    initialstate.check();
    while(!que.empty()) {
        auto from = que.front();
        que.pop();
        //from.print();
        if(from.gameclear()) {
            cout << from.cost << endl;
            return 0;
        }
        auto to = from;
        to.go();
        to.check();
        for(int i = 0; i < 6; i++) {
            if(i % 3 == 0) continue;
            to = from;
            to.rotateeye(i);
            to.check();
        }
        for(int i = 0; i < 6; i++) {
            if(i % 3 == 0) continue;
            to = from;
            to.rotatedice(i);
            to.check();
        }
        to = from;
        to.wash();
        to.check();
        to = from;
        to.nothing();
        to.check();
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 37584
final_rank: 6

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

typedef int_fast32_t int32;
typedef int_fast64_t int64;

const int32 inf = 1e9+7;
const int32 MOD = 1000000007;
const int64 llinf = 1e18;

#define YES(n) cout << ((n) ? "YES\n" : "NO\n"  )
#define Yes(n) cout << ((n) ? "Yes\n" : "No\n"  )
#define POSSIBLE(n) cout << ((n) ? "POSSIBLE\n" : "IMPOSSIBLE\n"  )
#define ANS(n) cout << (n) << "\n"
#define REP(i,n) for(int64 i=0;i<(n);++i)
#define FOR(i,a,b) for(int64 i=(a);i<(b);i++)
#define FORR(i,a,b) for(int64 i=(a);i>=(b);i--)
#define all(obj) (obj).begin(),(obj).end()
#define rall(obj) (obj).rbegin(),(obj).rend()
#define fi first
#define se second
#define pb(a) push_back(a)
typedef pair<int32,int32> pii;
typedef pair<int64,int64> pll;

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

const int32 dx[6] = {0,0,1,0,0,-1};
const int32 dy[6] = {0,1,0,0,-1,0};
const int32 dz[6] = {1,0,0,-1,0,0};


int32 n;
char a[33][33][33];
int32 sx,sy,sz;
// dp[x][y][z][目の向き][サイコロの向き][残り弱ネバネバターン][指輪回収済みか]
int32 dp[33][33][33][6][6][3][2];


struct cond{
  int32 x,y,z,eye,dice,rem,ring;
  cond(){}
  cond(int32 x,int32 y,int32 z,int32 eye,int32 dice,int32 rem,int32 ring):x(x),y(y),z(z),eye(eye),dice(dice),rem(rem),ring(ring){}

  cond front(){
    cond ret = *this;
    ret.x += dx[eye];
    ret.y += dy[eye];
    ret.z += dz[eye];
    if(ret.ok() && a[ret.x][ret.y][ret.z] == 'R')ret.ring = 1;
    return ret;
  }

  vector<cond> chEye(){
    vector<cond> ret;
    FOR(i,1,6){
      cond c = *this;
      if(i == 3)continue;
      c.eye = (c.eye + i) % 6;
      ret.pb(c);
    }
    return ret;
  }

  vector<cond> roollDice(){
    vector<cond> ret;
    FOR(i,1,6){
      cond c = *this;
      if(i == 3)continue;
      c.dice = (c.dice + i) % 6;
      ret.pb(c);
    }
    return ret;
  }

  cond wash(){
    cond ret = *this;
    ret.rem = 3;
    return ret;
  }

  cond wait(){
    return *this;
  }

  void fall(){
    if(rem == 0){
      while(!onthewall()){
        x += dx[dice];
        y += dy[dice];
        z += dz[dice];
        if(a[x][y][z] == 'R')ring = 1;
      }
      return;
    }

    while(true){
      cond ncond = *this;
      ncond.x += dx[dice];
      ncond.y += dy[dice];
      ncond.z += dz[dice];
      if(ncond.ok()){
        if(a[ncond.x][ncond.y][ncond.z] == 'R')ncond.ring = 1;
        *this = ncond;
      }else{
        return;
      }
    }
  }

  bool ok(){
    if(x < 0 || n <= x)return false;
    if(y < 0 || n <= y)return false;
    if(z < 0 || n <= z)return false;
    return a[x][y][z] != '#';
  }

  bool onthewall(){
    REP(i,6){
      if(x+dx[i] < 0 || n <= x+dx[i])continue;
      if(y+dy[i] < 0 || n <= y+dy[i])continue;
      if(z+dz[i] < 0 || n <= z+dz[i])continue;
      if(a[x+dx[i]][y+dy[i]][z+dz[i]] == '#')return true;
    }
    return false;
  }

  bool goal(){
    return x == sx && y == sy && z == sz && ring == 1;
  }
};

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n;
  FORR(z,n-1,0)REP(y,n)REP(x,n)cin >> a[x][y][z];
  REP(i,n)REP(j,n)REP(k,n){
    if(a[i][j][k] == 'S'){
      tie(sx,sy,sz) = tie(i,j,k);
      break;
    }
  }

  REP(x,n)REP(y,n)REP(z,n)REP(eye,6)REP(dice,6)REP(rem,3)REP(ring,2)
    dp[x][y][z][eye][dice][rem][ring] = inf;

  queue<pair<cond,int32>> que;

  auto push = [&](cond c, int32 d){
    if(!c.ok())return;
    c.fall();
    if(c.rem > 0)
      --c.rem;
    if(chmin(dp[c.x][c.y][c.z][c.eye][c.dice][c.rem][c.ring], d)){
      que.emplace(c,d);
    }
  };

  {
    cond scond(sx,sy,sz,0,3,0,0);
    push(scond, 0);
  }
  while(!que.empty()){
    cond ccond;
    int32 d;
    tie(ccond,d) = que.front();que.pop();

    if(ccond.goal()){
      ANS(d);
      return 0;
    }

    push(ccond.front(),d+1);
    for(auto c : ccond.chEye()){
      push(c,d+1);
    }
    if(ccond.onthewall() && ccond.rem == 0){
      for(auto c : ccond.roollDice()){
        push(c,d+1);
      }
    }
    if(ccond.rem == 0){
      push(ccond.wash(),d+1);
    }
    push(ccond.wait(),d+1);
  }
  return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 61812
final_rank: 8

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

typedef int_fast32_t int32;
typedef int_fast64_t int64;

const int32 inf = 1e9+7;
const int32 MOD = 1000000007;
const int64 llinf = 1e18;

#define YES(n) cout << ((n) ? "YES\n" : "NO\n"  )
#define Yes(n) cout << ((n) ? "Yes\n" : "No\n"  )
#define POSSIBLE(n) cout << ((n) ? "POSSIBLE\n" : "IMPOSSIBLE\n"  )
#define ANS(n) cout << (n) << "\n"
#define REP(i,n) for(int64 i=0;i<(n);++i)
#define FOR(i,a,b) for(int64 i=(a);i<(b);i++)
#define FORR(i,a,b) for(int64 i=(a);i>=(b);i--)
#define all(obj) (obj).begin(),(obj).end()
#define rall(obj) (obj).rbegin(),(obj).rend()
#define fi first
#define se second
#define pb(a) push_back(a)
typedef pair<int32,int32> pii;
typedef pair<int64,int64> pll;

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

const int32 dx[6] = {0,0,1,0,0,-1};
const int32 dy[6] = {0,1,0,0,-1,0};
const int32 dz[6] = {1,0,0,-1,0,0};


int32 n;
char a[33][33][33];
int32 sx,sy,sz;
// dp[x][y][z][目の向き][サイコロの向き][残り弱ネバネバターン][指輪回収済みか]
int32 dp[33][33][33][6][6][3][2];


struct cond{
  int32 x,y,z,eye,dice,rem,ring;
  cond(){}
  cond(int32 x,int32 y,int32 z,int32 eye,int32 dice,int32 rem,int32 ring):x(x),y(y),z(z),eye(eye),dice(dice),rem(rem),ring(ring){}

  cond front(){
    cond ret = *this;
    ret.x += dx[eye];
    ret.y += dy[eye];
    ret.z += dz[eye];
    if(ret.ok() && a[ret.x][ret.y][ret.z] == 'R')ret.ring = 1;
    return ret;
  }

  vector<cond> chEye(){
    vector<cond> ret;
    FOR(i,1,6){
      cond c = *this;
      if(i == 3)continue;
      c.eye = (c.eye + i) % 6;
      ret.pb(c);
    }
    return ret;
  }

  vector<cond> roollDice(){
    vector<cond> ret;
    FOR(i,1,6){
      cond c = *this;
      if(i == 3)continue;
      c.dice = (c.dice + i) % 6;
      ret.pb(c);
    }
    return ret;
  }

  cond wash(){
    cond ret = *this;
    ret.rem = 3;
    return ret;
  }

  cond wait(){
    return *this;
  }

  void fall(){
    if(rem == 0){
      while(!onthewall()){
        x += dx[dice];
        y += dy[dice];
        z += dz[dice];
        if(a[x][y][z] == 'R')ring = 1;
      }
      return;
    }

    while(true){
      cond ncond = *this;
      ncond.x += dx[dice];
      ncond.y += dy[dice];
      ncond.z += dz[dice];
      if(ncond.ok()){
        if(a[ncond.x][ncond.y][ncond.z] == 'R')ncond.ring = 1;
        *this = ncond;
      }else{
        return;
      }
    }
  }

  bool ok(){
    if(x < 0 || n <= x)return false;
    if(y < 0 || n <= y)return false;
    if(z < 0 || n <= z)return false;
    return a[x][y][z] != '#';
  }

  bool onthewall(){
    REP(i,6){
      if(x+dx[i] < 0 || n <= x+dx[i])continue;
      if(y+dy[i] < 0 || n <= y+dy[i])continue;
      if(z+dz[i] < 0 || n <= z+dz[i])continue;
      if(a[x+dx[i]][y+dy[i]][z+dz[i]] == '#')return true;
    }
    return false;
  }

  bool goal(){
    return x == sx && y == sy && z == sz && ring == 1;
  }
};

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n;
  FORR(z,n-1,0)REP(y,n)REP(x,n)cin >> a[x][y][z];
  REP(i,n)REP(j,n)REP(k,n){
    if(a[i][j][k] == 'S'){
      tie(sx,sy,sz) = tie(i,j,k);
      break;
    }
  }

  REP(x,n)REP(y,n)REP(z,n)REP(eye,6)REP(dice,6)REP(rem,3)REP(ring,2)
    dp[x][y][z][eye][dice][rem][ring] = inf;

  queue<pair<cond,int32>> que;

  auto push = [&](cond c, int32 d){
    if(!c.ok())return;
    if(c.rem > 0){
      c.fall();
      --c.rem;
    }
    if(chmin(dp[c.x][c.y][c.z][c.eye][c.dice][c.rem][c.ring], d)){
      que.emplace(c,d);
    }
  };

  cond scond(sx,sy,sz,0,3,0,0);
  push(scond, 0);
  while(!que.empty()){
    cond ccond;
    int32 d;
    tie(ccond,d) = que.front();que.pop();

    if(ccond.goal()){
      ANS(d);
      return 0;
    }

    push(ccond.front(),d+1);
    for(auto c : ccond.chEye()){
      push(c,d+1);
    }
    if(ccond.onthewall() && ccond.rem == 0){
      for(auto c : ccond.roollDice()){
        push(c,d+1);
      }
    }
    if(ccond.rem == 0){
      push(ccond.wash(),d+1);
    }
    push(ccond.wait(),d+1);
  }
  return 0;
}
accuracy: 0.5522388059701493
time_ms: 220
memory_kb: 62056
final_rank: 12

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

typedef int_fast32_t int32;
typedef int_fast64_t int64;

const int32 inf = 1e9+7;
const int32 MOD = 1000000007;
const int64 llinf = 1e18;

#define YES(n) cout << ((n) ? "YES\n" : "NO\n"  )
#define Yes(n) cout << ((n) ? "Yes\n" : "No\n"  )
#define POSSIBLE(n) cout << ((n) ? "POSSIBLE\n" : "IMPOSSIBLE\n"  )
#define ANS(n) cout << (n) << "\n"
#define REP(i,n) for(int64 i=0;i<(n);++i)
#define FOR(i,a,b) for(int64 i=(a);i<(b);i++)
#define FORR(i,a,b) for(int64 i=(a);i>=(b);i--)
#define all(obj) (obj).begin(),(obj).end()
#define rall(obj) (obj).rbegin(),(obj).rend()
#define fi first
#define se second
#define pb(a) push_back(a)
typedef pair<int32,int32> pii;
typedef pair<int64,int64> pll;

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

const int32 dx[6] = {0,0,1,0,0,-1};
const int32 dy[6] = {0,1,0,0,-1,0};
const int32 dz[6] = {1,0,0,-1,0,0};


int32 n;
char a[33][33][33];
int32 sx,sy,sz;
// dp[x][y][z][目の向き][サイコロの向き][残り弱ネバネバターン][指輪回収済みか]
int32 dp[33][33][33][6][6][3][2];


struct cond{
  int32 x,y,z,eye,dice,rem,ring;
  cond(){}
  cond(int32 x,int32 y,int32 z,int32 eye,int32 dice,int32 rem,int32 ring):x(x),y(y),z(z),eye(eye),dice(dice),rem(rem),ring(ring){}

  cond front(){
    cond ret = *this;
    ret.x += dx[eye];
    ret.y += dy[eye];
    ret.z += dz[eye];
    if(a[ret.x][ret.y][ret.z] == 'R')ret.ring = 1;
    return ret;
  }

  vector<cond> chEye(){
    vector<cond> ret;
    FOR(i,1,6){
      cond c = *this;
      if(i == 3)continue;
      c.eye = (c.eye + i) % 6;
      ret.pb(c);
    }
    return ret;
  }

  vector<cond> roollDice(){
    vector<cond> ret;
    FOR(i,1,6){
      cond c = *this;
      if(i == 3)continue;
      c.dice = (c.dice + i) % 6;
      ret.pb(c);
    }
    return ret;
  }

  cond wash(){
    cond ret = *this;
    ret.rem = 3;
    return ret;
  }

  cond wait(){
    return *this;
  }

  void fall(){
    if(rem == 0){
      while(!onthewall()){
        x += dx[dice];
        y += dy[dice];
        z += dz[dice];
        if(a[x][y][z] == 'R')ring = 1;
      }
      return;
    }

    while(true){
      cond ncond = *this;
      ncond.x += dx[dice];
      ncond.y += dy[dice];
      ncond.z += dz[dice];
      if(ncond.ok()){
        if(a[ncond.x][ncond.y][ncond.z] == 'R')ncond.ring = 1;
        *this = ncond;
      }else{
        return;
      }
    }
  }

  bool ok(){
    if(x < 0 || n <= x)return false;
    if(y < 0 || n <= y)return false;
    if(z < 0 || n <= z)return false;
    return a[x][y][z] != '#';
  }

  bool onthewall(){
    REP(i,6){
      if(x+dx[i] < 0 || n <= x+dx[i])continue;
      if(y+dy[i] < 0 || n <= y+dy[i])continue;
      if(z+dz[i] < 0 || n <= z+dz[i])continue;
      if(a[x+dx[i]][y+dy[i]][z+dz[i] == '#'])return true;
    }
    return false;
  }

  bool goal(){
    return x == sx && y == sy && z == sz && ring == 1;
  }
};

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n;
  FORR(z,n-1,0)REP(y,n)REP(x,n)cin >> a[x][y][z];
  REP(i,n)REP(j,n)REP(k,n){
    if(a[i][j][k] == 'S'){
      tie(sx,sy,sz) = tie(i,j,k);
      break;
    }
  }

  REP(x,n)REP(y,n)REP(z,n)REP(eye,6)REP(dice,6)REP(rem,3)REP(ring,2)
    dp[x][y][z][eye][dice][rem][ring] = inf;

  queue<pair<cond,int32>> que;

  auto push = [&](cond c, int32 d){
    if(!c.ok())return;
    if(c.rem > 0){
      c.fall();
      --c.rem;
    }
    if(chmin(dp[c.x][c.y][c.z][c.eye][c.dice][c.rem][c.ring], d)){
      que.emplace(c,d);
    }
  };

  cond scond(sx,sy,sz,0,3,0,0);
  push(scond, 0);
  while(!que.empty()){
    cond ccond;
    int32 d;
    tie(ccond,d) = que.front();que.pop();

    if(ccond.goal()){
      ANS(d);
      return 0;
    }

    push(ccond.front(),d+1);
    for(auto c : ccond.chEye()){
      push(c,d+1);
    }
    if(ccond.onthewall() && ccond.rem == 0){
      for(auto c : ccond.roollDice()){
        push(c,d+1);
      }
    }
    if(ccond.rem == 0){
      push(ccond.wash(),d+1);
    }
    push(ccond.wait(),d+1);
  }
  return 0;
}
accuracy: 0.5522388059701493
time_ms: 230
memory_kb: 62072
final_rank: 14

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

typedef int_fast32_t int32;
typedef int_fast64_t int64;

const int32 inf = 1e9+7;
const int32 MOD = 1000000007;
const int64 llinf = 1e18;

#define YES(n) cout << ((n) ? "YES\n" : "NO\n"  )
#define Yes(n) cout << ((n) ? "Yes\n" : "No\n"  )
#define POSSIBLE(n) cout << ((n) ? "POSSIBLE\n" : "IMPOSSIBLE\n"  )
#define ANS(n) cout << (n) << "\n"
#define REP(i,n) for(int64 i=0;i<(n);++i)
#define FOR(i,a,b) for(int64 i=(a);i<(b);i++)
#define FORR(i,a,b) for(int64 i=(a);i>=(b);i--)
#define all(obj) (obj).begin(),(obj).end()
#define rall(obj) (obj).rbegin(),(obj).rend()
#define fi first
#define se second
#define pb(a) push_back(a)
typedef pair<int32,int32> pii;
typedef pair<int64,int64> pll;

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

const int32 dx[6] = {0,0,1,0,0,-1};
const int32 dy[6] = {0,1,0,0,-1,0};
const int32 dz[6] = {1,0,0,-1,0,0};


int32 n;
char a[33][33][33];
int32 sx,sy,sz;
// dp[x][y][z][目の向き][サイコロの向き][残り弱ネバネバターン][指輪回収済みか]
int32 dp[33][33][33][6][6][3][2];


struct cond{
  int32 x,y,z,eye,dice,rem,ring;
  cond(){}
  cond(int32 x,int32 y,int32 z,int32 eye,int32 dice,int32 rem,int32 ring):x(x),y(y),z(z),eye(eye),dice(dice),rem(rem),ring(ring){}

  cond front(){
    cond ret = *this;
    ret.x += dx[eye];
    ret.y += dy[eye];
    ret.z += dz[eye];
    if(a[ret.x][ret.y][ret.z] == 'R')ret.ring = 1;
    return ret;
  }

  vector<cond> chEye(){
    vector<cond> ret;
    FOR(i,1,6){
      cond c = *this;
      if(i == 3)continue;
      c.eye = (c.eye + i) % 6;
      ret.pb(c);
    }
    return ret;
  }

  vector<cond> roollDice(){
    vector<cond> ret;
    FOR(i,1,6){
      cond c = *this;
      if(i == 3)continue;
      c.dice = (c.dice + i) % 6;
      ret.pb(c);
    }
    return ret;
  }

  cond wash(){
    cond ret = *this;
    ret.rem = 3;
    return ret;
  }

  cond wait(){
    return *this;
  }

  void fall(){
    if(rem == 0){
      while(!onthewall()){
        x += dx[dice];
        y += dy[dice];
        z += dz[dice];
      }
      return;
    }

    while(true){
      cond ncond = *this;
      ncond.x += dx[dice];
      ncond.y += dy[dice];
      ncond.z += dz[dice];
      if(ncond.ok()){
        if(a[ncond.x][ncond.y][ncond.z] == 'R')ncond.ring = 1;
        *this = ncond;
      }else{
        return;
      }
    }
  }

  bool ok(){
    if(x < 0 || n <= x)return false;
    if(y < 0 || n <= y)return false;
    if(z < 0 || n <= z)return false;
    return a[x][y][z] != '#';
  }

  bool onthewall(){
    REP(i,6){
      if(x+dx[i] < 0 || n <= x+dx[i])continue;
      if(y+dy[i] < 0 || n <= y+dy[i])continue;
      if(z+dz[i] < 0 || n <= z+dz[i])continue;
      if(a[x+dx[i]][y+dy[i]][z+dz[i] == '#'])return true;
    }
    return false;
  }

  bool goal(){
    return x == sx && y == sy && z == sz && ring == 1;
  }
};

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n;
  FORR(z,n-1,0)REP(y,n)REP(x,n)cin >> a[x][y][z];
  REP(i,n)REP(j,n)REP(k,n){
    if(a[i][j][k] == 'S'){
      tie(sx,sy,sz) = tie(i,j,k);
      break;
    }
  }

  REP(x,n)REP(y,n)REP(z,n)REP(eye,6)REP(dice,6)REP(rem,3)REP(ring,2)
    dp[x][y][z][eye][dice][rem][ring] = inf;

  queue<pair<cond,int32>> que;

  auto push = [&](cond c, int32 d){
    if(!c.ok())return;
    if(c.rem > 0){
      c.fall();
      --c.rem;
    }
    if(chmin(dp[c.x][c.y][c.z][c.eye][c.dice][c.rem][c.ring], d)){
      que.emplace(c,d);
    }
  };

  cond scond(sx,sy,sz,0,3,0,0);
  push(scond, 0);
  while(!que.empty()){
    cond ccond;
    int32 d;
    tie(ccond,d) = que.front();que.pop();

    if(ccond.goal()){
      ANS(d);
      return 0;
    }

    push(ccond.front(),d+1);
    for(auto c : ccond.chEye()){
      push(c,d+1);
    }
    if(ccond.onthewall() && ccond.rem == 0){
      for(auto c : ccond.roollDice()){
        push(c,d+1);
      }
    }
    if(ccond.rem == 0){
      push(ccond.wash(),d+1);
    }
    push(ccond.wait(),d+1);
  }
  return 0;
}
accuracy: 0.5522388059701493
time_ms: 220
memory_kb: 62072
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define For(i, a, b) for (int(i) = (int)(a); (i) < (int)(b); ++(i))
#define rFor(i, a, b) for (int(i) = (int)(a)-1; (i) >= (int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
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 (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T>
T div_floor(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a >= 0 ? a / b : (a + 1) / b - 1;
}
template <class T>
T div_ceil(T a, T b) {
    if (b < 0) a *= -1, b *= -1;
    return a > 0 ? (a - 1) / b + 1 : a / b;
}

constexpr lint mod = 1000000007;
constexpr lint INF = mod * mod;
constexpr int MAX = 100010;

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

struct state {
    int x, y, z, eye, down, neba, ring;
};

int n, sy, sz;
string c[35][35];
int dist[35][35][35][6][6][3][2];
int ex[35][35][35][6], ey[35][35][35][6], ez[35][35][35][6];
int er[35][35][35][6];

bool in(int x, int y, int z) {
    return 0 <= x && x < n && 0 <= y && y < n && 0 <= z && z < n;
}

void calc_end() {
    rep(x, n) rep(y, n) rep(z, n) rep(d, 6) {
        if (c[x][y][z] != '#') {
            int nx = x, ny = y, nz = z;
            er[x][y][z][d] |= (c[x][y][z] == 'R');
            while (in(nx + dx[d], ny + dy[d], nz + dz[d]) &&
                   c[nx + dx[d]][ny + dy[d]][nz + dz[d]] != '#') {
                nx += dx[d];
                ny += dy[d];
                nz += dz[d];
                er[x][y][z][d] |= (c[nx][ny][nz] == 'R');
            }
            ex[x][y][z][d] = nx;
            ey[x][y][z][d] = ny;
            ez[x][y][z][d] = nz;
        }
    }
}

int main() {
    scanf("%d", &n);
    rep(i, n) rep(j, n) {
        cin >> c[i][j];
        rep(k, n) if (c[i][j][k] == 'S') sy = j, sz = k;
    }
    calc_end();

    rep(i, n) rep(j, n) rep(k, n) rep(e, 6) rep(d, 6) rep(neba, 3)
        rep(ring, 2) {
        dist[i][j][k][e][d][neba][ring] = mod;
    }
    dist[0][sy][sz][5][0][0][0];
    queue<state> que;
    que.push({0, sy, sz, 5, 0, 0, 0});
    dist[0][sy][sz][5][0][0][0] = 0;
    while (!que.empty()) {
        auto s = que.front();
        que.pop();
        /*printf("x:%d y:%d z:%d eye:%d dn:%d neb:%d r:%d\n", s.x, s.y, s.z,
               s.eye, s.down, s.neba, s.ring);*/
        int d = dist[s.x][s.y][s.z][s.eye][s.down][s.neba][s.ring];
        // printf("%d\n", d);
        {  // move
            int nx = s.x + dx[s.eye], ny = s.y + dy[s.eye],
                nz = s.z + dz[s.eye];
            int nn = max(0, s.neba - 1), nr = (s.ring | (c[nx][ny][nz] == 'R'));
            if (in(nx, ny, nz) && c[nx][ny][nz] != '#') {
                int nr = s.ring;
                if (s.neba) {
                    nx = ex[nx][ny][nz][s.down];
                    ny = ey[nx][ny][nz][s.down];
                    nz = ez[nx][ny][nz][s.down];
                    nr |= er[nx][ny][nz][s.down];
                }
                if (chmin(dist[nx][ny][nz][s.eye][s.down][nn][nr], d + 1)) {
                    que.push({nx, ny, nz, s.eye, s.down, nn, nr});
                }
            }
        }
        {  // eye
            int nn = max(0, s.neba - 1);
            rep(ne, 6) if (ne + s.eye != 5) {
                int nx = s.x, ny = s.y, nz = s.z;
                int nr = s.ring;
                if (s.neba) {
                    nx = ex[nx][ny][nz][s.down];
                    ny = ey[nx][ny][nz][s.down];
                    nz = ez[nx][ny][nz][s.down];
                    nr |= er[nx][ny][nz][s.down];
                }
                if (chmin(dist[nx][ny][nz][ne][s.down][nn][nr], d + 1)) {
                    que.push({nx, ny, nz, ne, s.down, nn, nr});
                }
            }
        }
        if (s.neba == 0) {  // dice
            int nn = max(0, s.neba - 1);
            rep(ndn, 6) if (s.down + ndn != 5) {
                int ne;
                if (s.eye == s.down)
                    ne = ndn;
                else if (s.eye == 5 - s.down)
                    ne = 5 - ndn;
                else{
                    if (ndn == s.eye) ne = 5 - s.down;
                    else if (ndn == 5-s.eye)
                        ne = s.down;
                    else ne = s.eye;
                }
                if (chmin(dist[s.x][s.y][s.z][ne][ndn][nn][s.ring], d + 1)) {
                    que.push({s.x, s.y, s.z, ne, ndn, nn, s.ring});
                }
            }
        }
        if (s.neba == 0) {  // neba
            int nn = 2;
            int nx = ex[s.x][s.y][s.z][s.down], ny = ey[s.x][s.y][s.z][s.down],
                nz = ez[s.x][s.y][s.z][s.down];
            int nr = (s.ring | er[s.x][s.y][s.z][s.down]);
            if (chmin(dist[nx][ny][nz][s.eye][s.down][nn][nr], d + 1)) {
                que.push({nx, ny, nz, s.eye, s.down, nn, nr});
            }
        }
        {  // nop
            int nn = max(0, s.neba - 1);
            int nx = s.x, ny = s.y, nz = s.z;
            int nr = s.ring;
            if (s.neba) {
                nx = ex[s.x][s.y][s.z][s.down], ny = ey[s.x][s.y][s.z][s.down],
                nz = ez[s.x][s.y][s.z][s.down];
                nr = (s.ring | er[s.x][s.y][s.z][s.down]);
            }
            if (chmin(dist[nx][ny][nz][s.eye][s.down][nn][nr], d + 1)) {
                que.push({nx, ny, nz, s.eye, s.down, nn, nr});
            }
        }
    }

    int ans = mod;
    rep(e, 6) rep(d, 6) rep(neba, 3) {
        chmin(ans, dist[0][sy][sz][e][d][neba][1]);
    }
    printf("%d\n", ans);
    /*printf("%d %d %d %d\n", ex[0][sy][sz][0], ey[0][sy][sz][0],
           ez[0][sy][sz][0], er[0][sy][sz][0]);*/
}
accuracy: 0.07462686567164178
time_ms: 50
memory_kb: 39072
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using uint = unsigned;
using pcc = pair<char, char>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
using tuplis = array<ll, 3>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;
const ll LINF=0x1fffffffffffffff;
const ll MINF=0x7fffffffffff;
const int INF=0x3fffffff;
const int MOD=1000000007;
const int MODD=998244353;
const ld DINF=numeric_limits<ld>::infinity();
const ld EPS=1e-9;
const ld PI=3.1415926535897932;
const ll dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const ll dy[] = {1, 0, -1, 0, 1, 1, -1, -1};
#define overload4(_1,_2,_3,_4,name,...) name
#define overload3(_1,_2,_3,name,...) name
#define rep1(n) for(ll i=0;i<n;++i)
#define rep2(i,n) for(ll i=0;i<n;++i)
#define rep3(i,a,b) for(ll i=a;i<b;++i)
#define rep4(i,a,b,c) for(ll i=a;i<b;i+=c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(ll i=n;i--;)
#define rrep2(i,n) for(ll i=n;i--;)
#define rrep3(i,a,b) for(ll i=b;i-->(a);)
#define rrep4(i,a,b,c) for(ll i=(a)+((b)-(a)-1)/(c)*(c);i>=(a);i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define each1(i,a) for(auto&&i:a)
#define each2(x,y,a) for(auto&&[x,y]:a)
#define each3(x,y,z,a) for(auto&&[x,y,z]:a)
#define each(...) overload4(__VA_ARGS__,each3,each2,each1)(__VA_ARGS__)
#define all1(i) begin(i),end(i)
#define all2(i,a) begin(i),begin(i)+a
#define all3(i,a,b) begin(i)+a,begin(i)+b
#define all(...) overload3(__VA_ARGS__,all3,all2,all1)(__VA_ARGS__)
#define rall1(i) (i).rbegin(),(i).rend()
#define rall2(i,k) (i).rbegin(),(i).rbegin()+k
#define rall3(i,a,b) (i).rbegin()+a,(i).rbegin()+b
#define rall(...) overload3(__VA_ARGS__,rall3,rall2,rall1)(__VA_ARGS__)
#define sum(...) accumulate(all(__VA_ARGS__),0LL)
#define dsum(...) accumulate(all(__VA_ARGS__),0.0L)
#define Msum(...) accumulate(all(__VA_ARGS__),0_M)
#define elif else if
#define unless(a) if(!(a))
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T> bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }
vector<ll> iota(ll n){ vector<ll> a(n); iota(a.begin(), a.end(), 0); return a; }
vector<pll> factor(ull x){ vector<pll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans.push_back({i, 1}); while((x /= i) % i == 0) ans.back().second++; } if(x != 1) ans.push_back({x, 1}); return ans; }
map<ll,ll> factor_map(ull x){ map<ll,ll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans[i] = 1; while((x /= i) % i == 0) ans[i]++; } if(x != 1) ans[x] = 1; return ans; }
vector<ll> divisor(ull x){ vector<ll> ans; for(ull i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); rrep(ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
template<class T> unordered_map<T, ll> press(vector<T> a){ Uniq(a); unordered_map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
template<class T> map<T, ll> press_map(vector<T> a){ Uniq(a); map<T, ll> ans; rep(a.size()) ans[a[i]] = i; return ans; }
int scan(){ return getchar(); }
void scan(int& a){ scanf("%d", &a); }
void scan(unsigned& a){ scanf("%u", &a); }
void scan(long& a){ scanf("%ld", &a); }
void scan(long long& a){ scanf("%lld", &a); }
void scan(unsigned long long& a){ scanf("%llu", &a); }
void scan(char& a){ do{ a = getchar(); }while(a == ' ' || a == '\n'); }
void scan(float& a){ scanf("%f", &a); }
void scan(double& a){ scanf("%lf", &a); }
void scan(long double& a){ scanf("%Lf", &a); }
void scan(vector<bool>& a){ for(unsigned i = 0; i < a.size(); i++){ int b; scan(b); a[i] = b; } }
void scan(char a[]){ scanf("%s", a); }
void scan(string& a){ cin >> a; }
template<class T> void scan(vector<T>&);
template<class T, size_t size> void scan(array<T, size>&);
template<class T, class L> void scan(pair<T, L>&);
template<class T, size_t size> void scan(T(&)[size]);
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
template<class T> void scan(deque<T>& a){ for(auto&& i : a) scan(i); }
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i); }
template<class T, class L> void scan(pair<T, L>& p){ scan(p.first); scan(p.second); }
template<class T, size_t size> void scan(T (&a)[size]){ for(auto&& i : a) scan(i); }
template<class T> void scan(T& a){ cin >> a; }
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){ scan(head); in(tail...); }
void print(){ putchar(' '); }
void print(bool a){ printf("%d", a); }
void print(int a){ printf("%d", a); }
void print(unsigned a){ printf("%u", a); }
void print(long a){ printf("%ld", a); }
void print(long long a){ printf("%lld", a); }
void print(unsigned long long a){ printf("%llu", a); }
void print(char a){ printf("%c", a); }
void print(char a[]){ printf("%s", a); }
void print(const char a[]){ printf("%s", a); }
void print(float a){ printf("%.15f", a); }
void print(double a){ printf("%.15f", a); }
void print(long double a){ printf("%.15Lf", a); }
void print(const string& a){ for(auto&& i : a) print(i); }
template<class T> void print(const complex<T>& a){ if(a.real() >= 0) print('+'); print(a.real()); if(a.imag() >= 0) print('+'); print(a.imag()); print('i'); }
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ putchar(' '); print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ print(p.first); putchar(' '); print(p.second); }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ putchar(' '); print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
#ifdef DEBUG
inline ll __lg(ull __n){ return sizeof(ull) * __CHAR_BIT__  - 1 - __builtin_clzll(__n); }
#define debug(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...) void(0)
#endif
int first(bool i = true){ return out(i?"first":"second"); }
int First(bool i = true){ return out(i?"First":"Second"); }
int yes(bool i = true){ return out(i?"yes":"no"); }
int Yes(bool i = true){ return out(i?"Yes":"No"); }
int No(){ return out("No"); }
int YES(bool i = true){ return out(i?"YES":"NO"); }
int NO(){ return out("NO"); }
int Yay(bool i = true){ return out(i?"Yay!":":("); }
int possible(bool i = true){ return out(i?"possible":"impossible"); }
int Possible(bool i = true){ return out(i?"Possible":"Impossible"); }
int POSSIBLE(bool i = true){ return out(i?"POSSIBLE":"IMPOSSIBLE"); }
void Case(ll i){ printf("Case #%lld: ", i); }





signed main(){
    using tuplis=array<int,3>;
    const int dx[6]={1,0,0,0,0,-1};
    const int dy[6]={0,1,0,0,-1,0};
    const int dz[6]={0,0,1,-1,0,0};
    LL(n);
    char s[30][30][30];
    rep(x,n)rep(y,n)rep(z,n)in(s[x][y][z]);
    static int cost[30][30][30][6][6][3][2]; // x, y, z, eye, gravity, sticky, ring
    memset(cost,0x77,sizeof cost);
    bool onwall[30][30][30];
    memset(onwall,0x00,sizeof onwall);
    int sx=0,sy=0,sz=0,rx=0,ry=0,rz=0;
    rep(x,n)rep(y,n)rep(z,n){
        if(s[x][y][z]=='#')rep(6){
            int x2=x+dx[i],y2=y+dy[i],z2=z+dz[i];
            if(x2<0||n<=x2||y2<0||n<=y2||z2<0||n<=z2)continue;
            onwall[x2][y2][z2]=1;
        }
        elif(s[x][y][z]=='S'){
            sx=x; sy=y; sz=z;
        }
        elif(s[x][y][z]=='R'){
            rx=x; ry=y; rz=z;
        }
    }
    array<int,4> fall[30][30][30][6];
    array<int,4> fall_sticky[30][30][30][6];
    each(i,fall)each(j,i)each(k,j)each(l,k)l.fill(-1);
    each(i,fall_sticky)each(j,i)each(k,j)each(l,k)l.fill(-1);
    auto dfs1 = [&](int x, int y, int z, int g, auto dfs) -> array<int,4> {
        if(x<0||n<=x||y<0||n<=y||z<0||n<=z||s[x][y][z]=='#')return {-1,-1,-1,0};
        if(fall[x][y][z][g][0]!=-1)return fall[x][y][z][g];
        fall[x][y][z][g]=dfs(x+dx[g],y+dy[g],z+dz[g],g,dfs);
        if(fall[x][y][z][g][0]==-1)fall[x][y][z][g]={x,y,z,0};
        if(x==rx&&y==ry&&z==rz)fall[x][y][z][g][3]=1;
        return fall[x][y][z][g];
    };
    rep(x,n)rep(y,n)rep(z,n)rep(g,6)dfs1(x,y,z,g,dfs1);
    auto dfs2 = [&](int x, int y, int z, int g, auto dfs) -> array<int,4> {
        if(x<0||n<=x||y<0||n<=y||z<0||n<=z||s[x][y][z]=='#')return {-1,-1,-1,0};
        if(fall_sticky[x][y][z][g][0]!=-1)return fall_sticky[x][y][z][g];
        if(onwall[x][y][z])return fall_sticky[x][y][z][g]={x,y,z,x==rx&&y==ry&&z==rz};
        fall_sticky[x][y][z][g]=dfs(x+dx[g],y+dy[g],z+dz[g],g,dfs);
        if(fall_sticky[x][y][z][g][0]==-1)fall_sticky[x][y][z][g]={x,y,z,0};
        if(x==rx&&y==ry&&z==rz)fall_sticky[x][y][z][g][3]=1;
        return fall_sticky[x][y][z][g];
    };
    rep(x,n)rep(y,n)rep(z,n)rep(g,6)dfs2(x,y,z,g,dfs2);
    queue<tuple<int,int,int,int,int,int,int>>q;
    cost[sx][sy][sz][5][0][0][0]=0;
    q.emplace(sx,sy,sz,5,0,0,0);
    while(q.size()){
        const auto[x,y,z,eye,g,stick,ring]=q.front();
        const int cost2=cost[x][y][z][eye][g][stick][ring]+1;
        q.pop();
        if(stick){ // 何もしない
            const int x2=x,y2=y,z2=z,eye2=eye,g2=g,stick2=stick-1,ring2=ring;
            if(chmin(cost[x2][y2][z2][eye2][g2][stick2][ring2],cost2))q.emplace(x2,y2,z2,eye2,g2,stick2,ring2);
        }
        if(stick==0){ // 洗浄
            const auto[x2,y2,z2,r]=fall[x][y][z][g];
            const int eye2=eye,g2=g,stick2=2,ring2=ring||r;
            if(chmin(cost[x2][y2][z2][eye2][g2][stick2][ring2],cost2))q.emplace(x2,y2,z2,eye2,g2,stick2,ring2);
        }
        if(stick==0){ // 回転
            rep(g2,6)if(g2!=g&&g2+g!=5){
                const int x2=x,y2=y,z2=z,eye2=eye,stick2=stick,ring2=ring;
                if(chmin(cost[x2][y2][z2][eye2][g2][stick2][ring2],cost2))q.emplace(x2,y2,z2,eye2,g2,stick2,ring2);
            }
        }
        rep(eye2,6)if(eye2!=eye&&eye+eye2!=5){ // 目の位置
            const int x2=x,y2=y,z2=z,g2=g,stick2=max(0,stick-1),ring2=ring;
            if(chmin(cost[x2][y2][z2][eye2][g2][stick2][ring2],cost2))q.emplace(x2,y2,z2,eye2,g2,stick2,ring2);
        }
        // 前進
        const int x2=x+dx[eye],y2=y+dy[eye],z2=z+dz[eye],eye2=eye,g2=g,stick2=max(0,stick-1);
        unless(x2<0||n<=x2||y2<0||n<=y2||z2<0||n<=z2||s[x2][y2][z2]=='#'){
            const auto[x3,y3,z3,r]=stick?fall[x2][y2][z2][g2]:fall_sticky[x2][y2][z2][g2];
            const int ring2=ring||r;
            if(chmin(cost[x3][y3][z3][eye2][g2][stick2][ring2],cost2))q.emplace(x3,y3,z3,eye2,g2,stick2,ring2);
        }
    }
    int ans=INF;
    rep(eye,6)rep(g,6)rep(stick,3)chmin(ans,cost[sx][sy][sz][eye][g][stick][1]);
    out(ans);
}
accuracy: 1
time_ms: 70
memory_kb: 32824
final_rank: 1

code_snippet: //
// Created by yamunaku on 2020/05/16.
//

#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define repl(i, l, r) for(int i = (l); i < (r); i++)
#define per(i, n) for(int i = ((n)-1); i >= 0; i--)
#define perl(i, l, r) for(int i = ((r)-1); i >= (l); i--)
#define all(x) (x).begin(),(x).end()
#define MOD9 998244353
#define MOD1 1000000007
#define IINF 1000000000
#define LINF 1000000000000000000
#define SP <<" "<<
#define CYES cout<<"Yes"<<endl
#define CNO cout<<"No"<<endl
#define CFS cin.tie(0);ios::sync_with_stdio(false)
#define CST(x) cout<<fixed<<setprecision(x)

using ll = long long;
using ld = long double;
using vi = vector<int>;
using mti = vector<vector<int>>;
using vl = vector<ll>;
using mtl = vector<vector<ll>>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
template<typename T>
using heap = priority_queue<T, vector<T>, function<bool(const T, const T)>>;

struct status {
    int x;
    int y;
    int z;
    int dir;
    int g_dir;
    int get;
    int neb;
};

int fallx[30][30][30][6][2];
int fally[30][30][30][6][2];
int fallz[30][30][30][6][2];
int dist[30][30][30][6][6][2][3];

int main() {
    int n;
    cin >> n;
    vector<vi> next_dir = {
            {1, 2, 3, 4},
            {0, 2, 4, 5},
            {0, 1, 3, 5},
            {0, 2, 4, 5},
            {0, 1, 3, 5},
            {1, 2, 3, 4}
    };
    vi vx = {0, 1, 0, -1, 0, 0};
    vi vy = {0, 0, 1, 0, -1, 0};
    vi vz = {1, 0, 0, 0, 0, -1};
    vector<vector<string>> field(n, vector<string>(n)); // z, y, x wo wasurenai
    int sx, sy, rx, ry, rz;
    rep(z, n) {
        rep(y, n) {
            cin >> field[z][y];
            rep(x, n) {
                if (field[z][y][x] == 'S') sx = x, sy = y;
                if (field[z][y][x] == 'R') rx = x, ry = y, rz = z;
            }
        }
    }

    vector<mti> tuku(n, mti(n, vi(n, false)));
    rep(x, n) rep(y,n) rep(z,n){
        if(field[z][y][x] != '#') continue;
        rep(t, 6){
            int nx = x + vx[t];
            int ny = y + vy[t];
            int nz = z + vz[t];
            if(nx < 0 || n <= nx || ny < 0 || n <= ny || nz < 0 || n <= nz) continue;
            tuku[nz][ny][nx] = true;
        }
    }
    rep(x,n) rep(y, n) rep(z,n){
        rep(t, 6){
            int nx = x, ny = y, nz = z;
            while(1){
                if(nx < 0 || n <= nx || ny < 0 || n <=ny || nz < 0 || n <= nz){
                    nx -= vx[t];
                    ny -= vy[t];
                    nz -= vz[t];
                    break;
                }
                if(field[nz][ny][nx] == '#'){
                    nx -= vx[t];
                    ny -= vy[t];
                    nz -= vz[t];
                    break;
                }
                if(tuku[nz][ny][nx]) break;
                nx += vx[t];
                ny += vy[t];
                nz += vz[t];
            }
            fallx[x][y][z][t][0] = nx;
            fally[x][y][z][t][0] = ny;
            fallz[x][y][z][t][0] = nz;
        }
    }

    rep(x,n) rep(y, n) rep(z,n){
        rep(t, 6){
            int nx = x, ny = y, nz = z;
            while(1){
                if(nx < 0 || n <= nx || ny < 0 || n <= ny || nz < 0 || n <= nz){
                    nx -= vx[t];
                    ny -= vy[t];
                    nz -= vz[t];
                    break;
                }
                if(field[nz][ny][nx] == '#'){
                    nx -= vx[t];
                    ny -= vy[t];
                    nz -= vz[t];
                    break;
                }
                nx += vx[t];
                ny += vy[t];
                nz += vz[t];
            }
            fallx[x][y][z][t][1] = nx;
            fally[x][y][z][t][1] = ny;
            fallz[x][y][z][t][1] = nz;
        }
    }

    rep(x, n) rep(y, n) rep(z, n) {
        rep(d, 6) rep(gd, 6) rep(gt, 2) rep(nb, 3) dist[x][y][z][d][gd][gt][nb] = IINF;
    }

    queue<status> q;
    q.push({sx, sy, 0, 5, 0, 0, 0});
    dist[sx][sy][0][5][0][0][0] = 0;

    function<void(int, int, int, int, int, int, int, int)> mv = [&](int x, int y, int z, int d, int gd, int gt, int nb,
                                                                    int cost) {
        if (dist[x][y][z][d][gd][gt][nb] != IINF) return;
//        cout << "->" SP x SP y SP z SP d SP gd SP gt SP nb << endl;
        dist[x][y][z][d][gd][gt][nb] = cost + 1;
        q.push({x, y, z, d, gd, gt, nb});
        if (gt == 1 && x == sx && y == sy && z == 0) {
            cout << cost + 1 << endl;
            exit(0);
        }
    };

    function<bool(int, int, int, int, int, int)> get_ring = [&](int xl, int yl, int zl, int xr, int yr, int zr){
        if(xl > xr) swap(xl, xr);
        if(yl > yr) swap(yl, yr);
        if(zl > zr) swap(zl, zr);
        if(xl == rx){
            if(yl == ry){
                return zl <= rz && rz <= zr;
            }else if(zl == rz){
                return yl <= ry && ry <= yr;
            }
        }else{
            if(yl == ry && zl == rz){
                return xl <= rx && rx <= xr;
            }
        }
        return false;
    };

    while (!q.empty()) {
        auto sta = q.front();
        q.pop();
        int cost = dist[sta.x][sta.y][sta.z][sta.dir][sta.g_dir][sta.get][sta.neb];
//        cout << sta.x SP sta.y SP sta.z SP sta.dir SP sta.g_dir SP sta.get SP sta.neb << " : " << cost << endl;
        int nb = max(0, sta.neb - 1);

        // zensin
//        cout << "zensin" << endl;
        {
            int nx = sta.x + vx[sta.dir];
            int ny = sta.y + vy[sta.dir];
            int nz = sta.z + vz[sta.dir];
//            cout << nx SP ny SP nz << endl;
            if (0 <= nx && nx < n && 0 <= ny && ny < n && 0 <= nz && nz < n) {
                if (field[nz][ny][nx] != '#') {
                    int tx, ty, tz;
                    if(sta.neb == 0){
                        tx = fallx[nx][ny][nz][sta.g_dir][0];
                        ty = fally[nx][ny][nz][sta.g_dir][0];
                        tz = fallz[nx][ny][nz][sta.g_dir][0];
                    }else{
                        tx = fallx[nx][ny][nz][sta.g_dir][1];
                        ty = fally[nx][ny][nz][sta.g_dir][1];
                        tz = fallz[nx][ny][nz][sta.g_dir][1];
                    }
                    int gt = sta.get || get_ring(nx, ny, nz, tx, ty, tz);
                    mv(tx, ty, tz, sta.dir, sta.g_dir, gt, nb, cost);
                }
            }
        }
//        cout << "me" << endl;

        // me idou
        for (auto nd : next_dir[sta.dir]) {
            mv(sta.x, sta.y, sta.z, nd, sta.g_dir, sta.get, nb, cost);
        }
//        cout << "kaiten" << endl;

        // kaiten
        if(sta.neb == 0){
            for (auto gd : next_dir[sta.g_dir]) {
                int nx, ny, nz;
                nx = fallx[sta.x][sta.y][sta.z][gd][0];
                ny = fally[sta.x][sta.y][sta.z][gd][0];
                nz = fallz[sta.x][sta.y][sta.z][gd][0];
                int gt = sta.get || get_ring(sta.x, sta.y, sta.z, nx, ny, nz);
                mv(nx, ny, nz, sta.dir, gd, gt, nb, cost);
            }
        }
//        cout << "senjo" << endl;

        // senjo
        if (sta.neb == 0) {
            int nx, ny, nz;
            nx = fallx[sta.x][sta.y][sta.z][sta.g_dir][1];
            ny = fally[sta.x][sta.y][sta.z][sta.g_dir][1];
            nz = fallz[sta.x][sta.y][sta.z][sta.g_dir][1];
            int gt = sta.get || get_ring(sta.x, sta.y, sta.z, nx, ny, nz);
            mv(nx, ny, nz, sta.dir, sta.g_dir, gt, 2, cost);
        }
//        cout << "mu" << endl;
        // mu
        if (sta.neb > 0) {
            mv(sta.x, sta.y, sta.z, sta.dir, sta.g_dir, sta.get, nb, cost);
        }

    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 31656
final_rank: 2

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

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

int INF = 1e9;
//const ll mod = 1000000007;
int N;
string S[35][35];
int dp[35][35][35][2][3][6][6];
//x座標 y座標 z座標 指輪の有無 残ネバネバ サイコロの向き 目の向き
int dx[6] = {1, 0, 0, -1, 0, 0};
int dy[6] = {0, 1, 0, 0, -1, 0};
int dz[6] = {0, 0, 1, 0, 0, -1};
int sx, sy, sz;
struct state;
queue<state> que;
struct state {
    int x, y, z, ring, turn, dice, eye, cost;
    state() {}
    void check() {
        if(chmin(dp[x][y][z][ring][turn][dice][eye], cost)) {
            que.push(*this);
            //cerr << "-> ";
            //print();
        }
    }
    void getring() {
        if(S[x][y][z] == 'R') ring = 1;
    }
    void go() {
        cost++;
        int newx = x + dx[eye];
        int newy = y + dy[eye];
        int newz = z + dz[eye];
        bool canmove = true;
        if(newx < 0 or newx >= N) canmove = false;
        if(newy < 0 or newy >= N) canmove = false;
        if(newz < 0 or newz >= N) canmove = false;
        if(canmove and S[newx][newy][newz] == '#') canmove = false;
        if(canmove) {
            x = newx;
            y = newy;
            z = newz;
        }
        getring();
        if(turn >= 1) drop();
    }
    void rotateeye(int idx) {
        cost++;
        eye = (eye + idx) % 6;
        getring();
        if(turn >= 1) drop();
    }
    void rotatedice(int idx) {
        cost++;
        if(turn == 0) dice = (dice + idx) % 6;
        getring();
        if(turn >= 1) drop();
    }
    void wash() {
        cost++;
        if(turn == 0) turn = 3;
        getring();
        if(turn >= 1) drop();
    }
    void nothing() {
        cost++;
        getring();
        if(turn >= 1) drop();
    }
    void drop() {
        turn--;
        while(true) {
            getring();
            int newx = x + dx[dice];
            int newy = y + dy[dice];
            int newz = z + dz[dice];
            if(newx < 0 or newx >= N) return;
            if(newy < 0 or newy >= N) return;
            if(newy < 0 or newy >= N) return;
            if(S[newx][newy][newz] == '#') return;
            x = newx;
            y = newy;
            z = newz;
            getring();
        }
    }
    bool gameclear() {
        if(x != sx) return false;
        if(y != sy) return false;
        if(z != sz) return false;
        if(ring != 1) return false;
        return true;
    }

    void print() {
        cerr << "state: " << x << " " << y << " " << z << " "<< ring << " " << turn << " " << eye << " " << dice << " " << cost << endl;
    }
};

int main() {
    //作問者とお話がしたいな
    cin >> N;
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            cin >> S[i][j];
            for(int k = 0; k < N; k++) {
                if(S[i][j][k] == 'S') {
                    sx = i;
                    sy = j;
                    sz = k;
                }
            }
        }
    }
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            for(int k = 0; k < N; k++) {
                for(int l = 0; l < 2; l++) {
                    for(int m = 0; m < 3; m++) {
                        for(int n = 0; n < 6; n++) {
                            for(int o = 0; o < 6; o++) {
                                dp[i][j][k][l][m][n][o] = INF;
                            }
                        }
                    }
                }
            }
        }
    }
    state initialstate;
    initialstate.x = sx;
    initialstate.y = sy;
    initialstate.z = sz;
    initialstate.ring = 0;
    initialstate.turn = 0;
    initialstate.dice = 0;
    initialstate.eye = 3;
    initialstate.cost = 0;
    initialstate.check();
    while(!que.empty()) {
        auto from = que.front();
        que.pop();
        //from.print();
        if(from.gameclear()) {
            cout << from.cost << endl;
            return 0;
        }
        auto to = from;
        to.go();
        to.check();
        for(int i = 0; i < 6; i++) {
            if(i % 3 == 0) continue;
            to = from;
            to.rotateeye(i);
            to.check();
        }
        for(int i = 0; i < 6; i++) {
            if(i % 3 == 0) continue;
            to = from;
            to.rotatedice(i);
            to.check();
        }
        to = from;
        to.wash();
        to.check();
        to = from;
        to.nothing();
        to.check();
    }
    return 0;
}
accuracy: 0.5522388059701493
time_ms: 90
memory_kb: 37788
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
//typedef complex<D> P;
#define F first
#define S second
const ll MOD=1000000007;
//const ll MOD=998244353;

template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){int i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}

const int MAX=32;
const int DIR=6;
const int STA=4;
const int INF=1e9;

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

int nxdir[6][4]={
                 {2,3,4,5},
                 {2,3,4,5},
                 {0,1,4,5},
                 {0,1,4,5},
                 {0,1,2,3},
                 {0,1,2,3}
};

int N;
char M[MAX][MAX][MAX];
int dp[2][STA][DIR][DIR][MAX][MAX][MAX];//cb,si
int sx,sy,sz;

void init(){
  for(int i=0;i<MAX;i++){
    for(int j=0;j<MAX;j++){
      for(int k=0;k<MAX;k++){
        M[i][j][k]='#';
      }
    }
  }
  for(int dn=0;dn<2;dn++){
    for(int st=0;st<STA;st++){
      for(int cb=0;cb<DIR;cb++){
        for(int si=0;si<DIR;si++){
          for(int i=0;i<MAX;i++){
            for(int j=0;j<MAX;j++){
              for(int k=0;k<MAX;k++){
                dp[dn][st][cb][si][i][j][k]=INF;
              }
            }
          }
        }
      }
    }
  }
  cin>>N;
  for(int i=1;i<=N;i++){
    for(int j=1;j<=N;j++){
      for(int k=1;k<=N;k++){
        cin>>M[i][j][k];
        if(M[i][j][k]=='S'){sx=i; sy=j; sz=k;}
      }
    }
  }
}

using TP=tuple<int,int,int,int,int,int,int>;

bool fall(int st,int si,int x,int y,int z){
  if(st!=0){return M[x+dx[si]][y+dy[si]][z+dz[si]]!='#';}
  for(int nb=0;nb<DIR;nb++){
    if(M[x+dx[nb]][y+dy[nb]][z+dz[nb]]=='#'){return false;}
  }
  return true;
}

void solve(){
  deque<TP> Q;
  dp[0][0][0][1][sx][sy][sz]=0;
  Q.push_back(TP(0,0,0,1,sx,sy,sz));
  while(!Q.empty()){
    TP tp=Q.front(); Q.pop_front();
    int dn=get<0>(tp);
    int st=get<1>(tp);
    int cb=get<2>(tp);
    int si=get<3>(tp);
    int x=get<4>(tp);
    int y=get<5>(tp);
    int z=get<6>(tp);
    int cost=dp[dn][st][cb][si][x][y][z];
    auto update=
      [&](int dn,int st,int cb,int si,int x,int y,int z,int dif){
        if(dp[dn][st][cb][si][x][y][z]>cost+dif){
          dp[dn][st][cb][si][x][y][z]=cost+dif;
          if(dif==0){Q.push_front(TP(dn,st,cb,si,x,y,z));}
          else{Q.push_back(TP(dn,st,cb,si,x,y,z));}
        }
      };
    if(dn==0 && M[x][y][z]=='R'){
      update(1,st,cb,si,x,y,z,0);
      continue;
    }
    if(fall(st,si,x,y,z)){
      update(dn,st,cb,si,x+dx[si],y+dy[si],z+dz[si],0);
      continue;
    }
    st=max(st-1,0);
    update(dn,st,cb,si,x,y,z,1);
    if(M[x+dx[cb]][y+dy[cb]][z+dz[cb]]!='#'){
      update(dn,st,cb,si,x+dx[cb],y+dy[cb],z+dz[cb],1);
    }
    for(auto nxcb:nxdir[cb]){
      update(dn,st,nxcb,si,x,y,z,1);
    }
    if(st==0){
      for(auto nxsi:nxdir[si]){
        update(dn,0,cb,nxsi,x,y,z,1);
      }
      update(dn,3,cb,si,x,y,z,1);
    }
  }
  int ans=INF;
  for(int st=0;st<STA;st++){
    for(int cb=0;cb<DIR;cb++){
      for(int si=0;si<DIR;si++){
        if(!fall(st,si,sx,sy,sz)){
          ans=min(ans,dp[1][st][cb][si][sx][sy][sz]);
        }
      }
    }
  }
  cout<<ans<<endl;
}

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

  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 42340
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#define rep(i, n) for(int i=0;i<(n);++i)
#define per(i, n) for(int i=(n)-1;i>=0;--i)
#define repa(i, n) for(int i=1;i<(n);++i)
#define foreach(i, n) for(auto &i:(n))
#define pii pair<int, int>
#define pll pair<long long, long long>
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
using ll = long long;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
using namespace std;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using v3ector = vvector<vector<t>>;
template<class t>
using v4ector = v3ector<vector<t>>;
template<class t>
using v5ector = v4ector<vector<t>>;
template<class t>
using v6ector = v5ector<vector<t>>;
template<class t>
using v7ector = v6ector<vector<t>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define OUTPUT(x) (output(x), output("\n"))
#else
#define OUTPUT(x) (void)0
#endif

ll modpow(ll x, ll b){
    ll res = 1;
    while(b){
        if(b&1)res = res * x % MOD;
        x = x * x % MOD;
        b>>=1;
    }
    return res;
}

ll modinv(ll x){
    return modpow(x, MOD-2);
}

bool was_output = false;
template<class t>
void output(t a){
    if(was_output)cout << " ";
    cout << a;
    was_output = true;
}
void outendl(){
    was_output = false;
    cout << endl;
}
ll in(){
    ll res;
    scanf("%lld", &res);
    return res;
}

int in_c(){
    char res;
    cin >> res;
    if(res=='.')return 0;
    if(res=='#')return 1;
    if(res=='S')return 2;
    if(res=='R')return 3;
    exit(1);
}

int mx[]={0,0,1,0,-1,0};
int my[]={0,1,0,-1,0,0};
int mz[]={-1,0,0,0,0,1};

int n;
v3ector<int> ground;

vector<int> get_nearby(int dir){
    if(dir==0)return {1,2,3,4};
    if(dir==1)return {0,2,4,5};
    if(dir==2)return {0,1,3,5};
    if(dir==3)return {0,2,4,5};
    if(dir==4)return {0,1,3,5};
    if(dir==5)return {1,2,3,4};
    cout << "get_nearby(" << dir << ") invalid argument!" << endl;
    exit(1);
}

bool is_in_wall(int x,int y,int z){
    return ground[x][y][z] == 1;
}

bool is_in(int x,int y,int z){
    int lp = min({x,y,z});
    int rp = max({x,y,z});
    return 0 <= lp && rp < n;
}

bool is_touching_wall(int x,int y,int z){
    rep(i,6){
        int tx = x + mx[i];
        int ty = y + my[i];
        int tz = z + mz[i];
        if(!is_in(tx,ty,tz))continue;
        if(!is_in_wall(tx,ty,tz))continue;
        return true;
    }
    return false;
}

void setup(){
    n = in();
    ground.resize(n,vvector<int>(n,vector<int>(n)));
    rep(z,n){
        rep(x,n){
            rep(y,n){
                ground[x][y][z] = in_c();
            }
        }
    }
}

bool get_ring(int px,int py,int pz){
    return ground[px][py][pz] == 3;
}

bool is_start(int px,int py,int pz){
    return ground[px][py][pz] == 2;
}

tuple<int,int,int,int> fall_in_gravity(int px,int py,int pz,int gravity,bool wash){
    using T = tuple<int,int,int,int>;
    static v5ector<T> memo(n,v4ector<T>(n,v3ector<T>(n,vvector<T>(6,vector<T>(3,forward_as_tuple(-1,-1,-1,-1))))));
    tuple<int,int,int,int> &it = memo[px][py][pz][gravity][wash];
    if(get<0>(it)>=0)return it;
    int flag = get_ring(px,py,pz);
    if(wash){
        while(true){
            int nx = px + mx[gravity];
            int ny = py + my[gravity];
            int nz = pz + mz[gravity];
            if(!is_in(nx,ny,nz))break;
            if(is_in_wall(nx,ny,nz))break;
            px = nx;
            py = ny;
            pz = nz;
            flag = flag || get_ring(px,py,pz);
        }
    }else{
        while(true){
            if(is_touching_wall(px,py,pz))break;
            int nx = px + mx[gravity];
            int ny = py + my[gravity];
            int nz = pz + mz[gravity];
            if(!is_in(nx,ny,nz))break;
            px = nx;
            py = ny;
            pz = nz;
            flag = flag || get_ring(px,py,pz);
        }
    }
    return it = forward_as_tuple(px,py,pz,flag);
}


int main(){
    setup();
    v7ector<int> fast(n,v6ector<int>(n,v5ector<int>(n,v4ector<int>(6,v3ector<int>(6,vvector<int>(3,vector<int>(2,INF)))))));
    queue<vector<int>> que;
    int sx;
    int sy;
    int sz;
    rep(i,n){
        rep(j,n){
            rep(k,n){
                if(is_start(i,j,k)){
                    que.emplace(vector<int>{i,j,k,0,5,0,0,0});
                    fast[i][j][k][0][5][0][0] = 0;
                    sx = i;
                    sy = j;
                    sz = k;
                }
            }
        }
    }

    while(que.size()){
        vector<int> d = que.front();
        que.pop();
        int px = d[0];
        int py = d[1];
        int pz = d[2];
        int forward = d[3];
        int gravity = d[4];
        int wash = d[5];
        int got_ring = d[6];
        int next_time = d[7] + 1;
        //粘着力なし
        if(wash){
            //前進
            [&](){
                int nx = px + mx[forward];
                int ny = py + my[forward];
                int nz = pz + mz[forward];
                if(!is_in(nx,ny,nz))return;
                if(is_in_wall(nx,ny,nz))return;
                int fx;
                int fy;
                int fz;
                int flag;
                tie(fx,fy,fz,flag) = fall_in_gravity(nx,ny,nz,gravity,wash);
                if(chmin(fast[fx][fy][fz][forward][gravity][wash-1][got_ring||flag],next_time)){
                    que.emplace(vector<int>{fx,fy,fz,forward,gravity,wash-1,got_ring||flag,next_time});
                }
            }();
            //回転
            foreach(dir,get_nearby(forward)){
                if(chmin(fast[px][py][pz][dir][gravity][wash-1][got_ring],next_time)){
                    que.emplace(vector<int>{px,py,pz,dir,gravity,wash-1,got_ring,next_time});
                }
            }
            //静止
            if(chmin(fast[px][py][pz][forward][gravity][wash-1][got_ring],next_time)){
                que.emplace(vector<int>{px,py,pz,forward,gravity,wash-1,got_ring,next_time});
            }
        }else{
            //前進
            [&](){
                int nx = px + mx[forward];
                int ny = py + my[forward];
                int nz = pz + mz[forward];
                if(!is_in(nx,ny,nz))return;
                if(is_in_wall(nx,ny,nz))return;
                int fx;
                int fy;
                int fz;
                int flag;
                tie(fx,fy,fz,flag) = fall_in_gravity(nx,ny,nz,gravity,wash);
                if(chmin(fast[fx][fy][fz][forward][gravity][wash][got_ring||flag],next_time)){
                    que.emplace(vector<int>{fx,fy,fz,forward,gravity,wash,got_ring||flag,next_time});
                }
            }();
            //洗浄
            {
                int fx;
                int fy;
                int fz;
                int flag;
                tie(fx,fy,fz,flag) = fall_in_gravity(px,py,pz,gravity,2);
                if(chmin(fast[fx][fy][fz][forward][gravity][2][got_ring||flag],next_time)){
                    que.emplace(vector<int>{fx,fy,fz,forward,gravity,2,got_ring||flag,next_time});
                }
            }
            //回転
            foreach(dir,get_nearby(forward)){
                if(chmin(fast[px][py][pz][dir][gravity][wash][got_ring],next_time)){
                    que.emplace(vector<int>{px,py,pz,dir,gravity,wash,got_ring,next_time});
                }
            }
            //サイコロ回転
            foreach(dir,get_nearby(gravity)){
                if(chmin(fast[px][py][pz][forward][dir][wash][got_ring],next_time)){
                    que.emplace(vector<int>{px,py,pz,forward,dir,wash,got_ring,next_time});
                }
            }
        }
    }

    int ans = INF;
    foreach(i,fast[sx][sy][sz]){
        foreach(j,i){
            foreach(k,j){
                chmin(ans,k[1]);
            }
        }
    }


    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 1050
memory_kb: 219536
final_rank: 10

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

#define REP(i, n) for ( int i = 0; i < (n); i++ )

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

const int rot[6][4] = {
        {2, 3, 4, 5},
        {2, 3, 4, 5},
        {0, 1, 4, 5},
        {0, 1, 4, 5},
        {2, 3, 0, 1},
        {2, 3, 0, 1},
};

struct state {
  int z, y, x, dice_d, cube_d, clean_turn, ring, cost;
  state(int z, int y, int x, int dice_d, int cube_d, int clean_turn, int ring, int cost):
          z(z), y(y), x(x), dice_d(dice_d), cube_d(cube_d), clean_turn(clean_turn), ring(ring), cost(cost) {}

  bool operator<(const state &s) const {
    return cost < s.cost;
  };

  bool operator>(const state &s) const {
    return cost > s.cost;
  };
};

int get_opposite(int d) {
  if ( d == 0 ) return 1;
  if ( d == 1 ) return 0;
  if ( d == 2 ) return 3;
  if ( d == 3 ) return 2;
  if ( d == 4 ) return 5;
  if ( d == 5 ) return 4;
}

int N;
char A[30][30][30]; // A[z][y][x]
int sx, sy, sz;

// リングを拾ったらtrue
bool down_neba(int &z, int &y, int &x, int d) {
  bool flag = false;
  if ( A[z][y][x] == 'R' ) flag = true;
  while ( 1 ) {
    bool flag2 = false;
    // 壁に隣接しているかどうか
    REP(i, 6) {
      int nz = z+dz[i], ny = y+dy[i], nx = x+dx[i];
      if ( nz < 0 || ny < 0 || nx < 0 || A[nz][ny][nx] == '#' ) {
        flag2 = true;
        break;
      }
    }
    if ( flag2 ) break;
    int nz = z+dz[d], ny = y+dy[d], nx = x+dx[d];
    if ( nz < 0 || ny < 0 || nx < 0 || A[nz][ny][nx] == '#' ) break;
    if ( A[nz][ny][nx] == 'R' ) flag = true;
    z = nz; y = ny; x = nx;
  }

  return flag;
}

bool down_clean(int &z, int &y, int &x, int d) {
  bool flag = false;
  if ( A[z][y][x] == 'R' ) flag = true;
  while ( 1 ) {
    int nz = z+dz[d], ny = y+dy[d], nx = x+dx[d];
    if ( nz < 0 || ny < 0 || nx < 0 || A[nz][ny][nx] == '#' ) break;
    if ( A[nz][ny][nx] == 'R' ) flag = true;
    z = nz; y = ny; x = nx;
  }

  return flag;
}

int solve() {
  bool used[30][30][30][6][6][3][2];
  fill_n(******used, 30*30*30*6*6*3*2, false);
  queue<state> Q;
  Q.push(state(sz, sy, sx, 1, 0, 0, 0, 0));
  while ( !Q.empty() ) {
    int z, y, x, dice_d, cube_d, clean_turn, ring, cost;
    {
      state s = Q.front(); Q.pop();
      z = s.z; y = s.y; x = s.x;
      dice_d = s.dice_d; cube_d = s.cube_d;
      clean_turn = s.clean_turn;
      ring = s.ring;
      cost = s.cost;
    }

    // ゴール条件
    if ( ring == 1 && z == sz && y == sy && x == sx ) {
      return cost;
    }

    if ( used[z][y][x][dice_d][cube_d][clean_turn][ring] ) continue;
    used[z][y][x][dice_d][cube_d][clean_turn][ring] = true;

    // 前進
    {
      int nz = z, ny = y, nx = x, nring = ring;
      nz += dz[cube_d]; ny += dy[cube_d]; nx += dx[cube_d];
      if ( !(nz < 0 || ny < 0 || nx < 0 || A[nz][ny][nx] == '#') ) {
        if ( clean_turn == 0 ) {
          nring |= down_neba(nz, ny, nx, dice_d);
        } else {
          nring |= down_clean(nz, ny, nx, dice_d);
        }
        Q.push(state(nz, ny, nx, dice_d, cube_d, max(0, clean_turn-1), nring, cost+1));
      }
    }

    // 目の位置を移動
    {
      REP(i, 4) {
        Q.push(state(z, y, x, dice_d, rot[cube_d][i], max(0, clean_turn-1), ring, cost+1));
      }
    }

    // サイコロの回転
    if ( clean_turn == 0 ){
      REP(i, 4) {
        Q.push(state(z, y, x, rot[dice_d][i], cube_d, max(0, clean_turn-1), ring, cost+1));
      }
    }

    // 洗浄
    if ( clean_turn == 0 ){
      int nz = z, ny = y, nx = x, nring = ring;
      nring |= down_clean(nz, ny, nx, dice_d);
      Q.push(state(nz, ny, nx, dice_d, cube_d, 2, nring, cost+1));
    }

    // 何もしない
    Q.push(state(z, y, x, dice_d, cube_d, max(0, clean_turn-1), ring, cost+1));
  }
}

signed main() {
  cin.tie( 0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin >> N;
  REP(z, N) REP(y, N) REP(x, N) {
    cin >> A[z][y][x];
    if ( A[z][y][x] == 'S' ) {
      sx = x; sy = y; sz = z;
    }
  }

  cout << solve() << endl;

  return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 25168
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
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;}

//INSERT ABOVE HERE
const int MAX_N = 33;
int dp[2][4][6][6][MAX_N][MAX_N][MAX_N];

/*
   0
 4   3
 2   1
   5
z: 5 -> 0, y: 3 -> 2, x: 4 -> 1
*/

int mz[6]={+1, 0, 0, 0, 0,-1};
int my[6]={ 0, 1, 0, 0,-1, 0};
int mx[6]={ 0, 0, 1,-1, 0, 0};

struct State{
  int with_ring;
  int wash_time;
  int gravity;
  int direction;
  int z,y,x;
  State(){}
  State(int with_ring,
        int wash_time,
        int gravity,
        int direction,
        int z,int y,int x):
    with_ring(with_ring),
    wash_time(wash_time),
    gravity(gravity),
    direction(direction),
    z(z),y(y),x(x){}

  void print(){
    cout<<z<<" "<<y<<" "<<x<<endl;
  }
};

int n;
char A[MAX_N][MAX_N][MAX_N];

bool is_valid(State cur){
  if(cur.z<0||cur.z>=n) return 0;
  if(cur.y<0||cur.y>=n) return 0;
  if(cur.x<0||cur.x>=n) return 0;
  if(A[cur.z][cur.y][cur.x]=='#') return 0;
  return 1;
}

bool is_wall(int z,int y,int x){
  if(z<0||z>=n) return 0;
  if(y<0||y>=n) return 0;
  if(x<0||x>=n) return 0;
  return (A[z][y][x]=='#');
}

bool touch_wall(State cur){
  for(int k=0;k<6;k++)
    if(is_wall(cur.z+mz[k],cur.y+my[k],cur.x+mx[k])) return 1;
  return 0;
}

bool is_ring(int z,int y,int x){
  if(z<0||z>=n) return 0;
  if(y<0||y>=n) return 0;
  if(x<0||x>=n) return 0;
  return (A[z][y][x]=='R');
}

State forward(State cur,int dir){
  cur.z+=mz[dir];
  cur.y+=my[dir];
  cur.x+=mx[dir];
  if(is_ring(cur.z,cur.y,cur.x)) cur.with_ring=1;
  return cur;
}

State drop(State cur){
  if(cur.wash_time){
    while(is_valid(forward(cur,cur.gravity)))
      cur=forward(cur,cur.gravity);
    cur.wash_time--;
  }else{
    while(!touch_wall(cur))
      cur=forward(cur,cur.gravity);
  }
  return cur;
}

queue<State> que;
void push(State cur,int value){
  int &res=dp[cur.with_ring][cur.wash_time][cur.gravity][cur.direction][cur.z][cur.y][cur.x];
  if(~res) return;
  res=value;
  que.emplace(cur);
}

signed main(){
  cin>>n;
  for(int z=n-1;z>=0;z--)
    for(int y=0;y<n;y++)
      for(int x=0;x<n;x++)
        cin>>A[z][y][x];

  State initial_state;
  initial_state.with_ring=0;
  initial_state.wash_time=0;
  initial_state.gravity=5;
  initial_state.direction=0;

  for(int y=0;y<n;y++){
    for(int x=0;x<n;x++){
      if(A[n-1][y][x]=='S'){
        initial_state.z=n-1;
        initial_state.y=y;
        initial_state.x=x;
        A[n-1][y][x]='.';
      }
    }
  }

  memset(dp,-1,sizeof(dp));
  push(initial_state,0);

  while(!que.empty()){
    State cur=que.front();que.pop();
    int value=dp[cur.with_ring][cur.wash_time][cur.gravity][cur.direction][cur.z][cur.y][cur.x];

    // cur.print();

    // Goal
    if(cur.with_ring && cur.z==n-1){
      cout<<value<<endl;
      break;
    }

    // 1. Forward
    if(is_valid(forward(cur,cur.direction))){
      State nxt=forward(cur,cur.direction);
      push(drop(nxt),value+1);
    }

    // 2. Rotate direction
    for(int k=0;k<6;k++){
      if(k==cur.direction) continue;
      if(k+cur.direction==5) continue;
      State nxt=cur;
      nxt.direction=k;
      push(drop(nxt),value+1);
    }

    // 3. Rotate gravity
    for(int k=0;k<6;k++){
      if(cur.wash_time) continue;
      if(k==cur.gravity) continue;
      if(k+cur.gravity==5) continue;
      State nxt=cur;
      nxt.gravity=k;
      push(drop(nxt),value+1);
    }

    // 4. Wash Mr. Cube
    if(!cur.wash_time){
      State nxt=cur;
      nxt.wash_time=3;
      push(drop(nxt),value+1);
    }

    // 5. Do nothing
    push(drop(cur),value+1);
  }

  return 0;
}
accuracy: 1
time_ms: 520
memory_kb: 45332
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int ull;
typedef long long int ll;
typedef pair<ll,ll> pll;
typedef long double D;
//typedef complex<D> P;
#define F first
#define S second
const ll MOD=1000000007;
//const ll MOD=998244353;

template<typename T,typename U>istream & operator >> (istream &i,pair<T,U> &A){i>>A.F>>A.S; return i;}
template<typename T>istream & operator >> (istream &i,vector<T> &A){for(auto &I:A){i>>I;} return i;}
template<typename T,typename U>ostream & operator << (ostream &o,const pair<T,U> &A){o<<A.F<<" "<<A.S; return o;}
template<typename T>ostream & operator << (ostream &o,const vector<T> &A){int i=A.size(); for(auto &I:A){o<<I<<(--i?" ":"");} return o;}

const int MAX=32;
const int DIR=6;
const int STA=4;
const int INF=1e9;

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

int nxdir[6][4]={
                 {2,3,4,5},
                 {2,3,4,5},
                 {0,1,4,5},
                 {0,1,4,5},
                 {0,1,2,3},
                 {0,1,2,3}
};

int N;
char M[MAX][MAX][MAX];
int dp[2][STA][DIR][DIR][MAX][MAX][MAX];//cb,si
int sx,sy,sz;

void init(){
  for(int i=0;i<MAX;i++){
    for(int j=0;j<MAX;j++){
      for(int k=0;k<MAX;k++){
        M[i][j][k]='#';
      }
    }
  }
  for(int dn=0;dn<2;dn++){
    for(int st=0;st<STA;st++){
      for(int cb=0;cb<DIR;cb++){
        for(int si=0;si<DIR;si++){
          for(int i=0;i<MAX;i++){
            for(int j=0;j<MAX;j++){
              for(int k=0;k<MAX;k++){
                dp[dn][st][cb][si][i][j][k]=INF;
              }
            }
          }
        }
      }
    }
  }
  cin>>N;
  for(int i=1;i<=N;i++){
    for(int j=1;j<=N;j++){
      for(int k=1;k<=N;k++){
        cin>>M[i][j][k];
        if(M[i][j][k]=='S'){sx=i; sy=j; sz=k;}
      }
    }
  }
}

using TP=tuple<int,int,int,int,int,int,int>;

bool fall(int st,int si,int x,int y,int z){
  if(st!=0){return M[x+dx[si]][y+dy[si]][z+dz[si]]!='#';}
  for(int nb=0;nb<DIR;nb++){
    if(M[x+dx[nb]][y+dy[nb]][z+dz[nb]]=='#'){return false;}
  }
  return true;
}

void solve(){
  deque<TP> Q;
  dp[0][0][0][1][sx][sy][sz]=0;
  Q.push_back(TP(0,0,0,1,sx,sy,sz));
  while(!Q.empty()){
    TP tp=Q.front(); Q.pop_front();
    int dn=get<0>(tp);
    int st=get<1>(tp);
    int cb=get<2>(tp);
    int si=get<3>(tp);
    int x=get<4>(tp);
    int y=get<5>(tp);
    int z=get<6>(tp);
    int cost=dp[dn][st][cb][si][x][y][z];
    auto update=
      [&](int dn,int st,int cb,int si,int x,int y,int z,int dif){
        if(dp[dn][st][cb][si][x][y][z]>cost+dif){
          dp[dn][st][cb][si][x][y][z]=cost+dif;
          if(dif==0){Q.push_front(TP(dn,st,cb,si,x,y,z));}
          else{Q.push_back(TP(dn,st,cb,si,x,y,z));}
        }
      };
    if(dn==0 && M[x][y][z]=='R'){
      update(1,st,cb,si,x,y,z,0);
      continue;
    }
    if(fall(st,si,x,y,z)){
      update(dn,st,cb,si,x+dx[si],y+dy[si],z+dz[si],0);
      continue;
    }
    st=max(st-1,0);
    update(dn,st,cb,si,x,y,z,1);
    if(M[x+dx[cb]][y+dy[cb]][z+dz[cb]]!='#'){
      update(dn,st,cb,si,x+dx[cb],y+dy[cb],z+dz[cb],1);
    }
    for(auto nxcb:nxdir[cb]){
      update(dn,st,nxcb,si,x,y,z,1);
    }
    if(st==0){
      for(auto nxsi:nxdir[si]){
        update(dn,0,cb,nxsi,x,y,z,1);
      }
      update(dn,3,cb,si,x,y,z,1);
    }
  }
  int ans=INF;
  for(int st=0;st<STA;st++){
    for(int cb=0;cb<DIR;cb++){
      for(int si=0;si<DIR;si++){
        if(!fall(st,si,sx,sy,sz)){
          ans=min(ans,dp[1][st][cb][si][sx][sy][sz]);
        }
      }
    }
  }
  cout<<ans<<endl;
}

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

  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 42324
final_rank: 4

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

int DZ[]={-1,0,0,0,0,1};
int DY[]={0,-1,0,0,1,0};
int DX[]={0,0,-1,1,0,0};

struct Dice{
  int s[6];
  Dice(){
  	r(i,6) s[i]=i;
  }
  void roll(int c){
    //the view from above
    // N
    //W E
    // S
    //s[0]:top
    //s[1]:south
    //s[2]:east
    //s[3]:west
    //s[4]:north
    //s[5]:bottom
    int b;
    if(c==0){
      b=s[0];
      s[0]=s[3];
      s[3]=s[5];
      s[5]=s[2];
      s[2]=b;
    }
    if(c==1){
      b=s[0];
      s[0]=s[2];
      s[2]=s[5];
      s[5]=s[3];
      s[3]=b;
    }
    if(c==2){
      b=s[0];
      s[0]=s[1];
      s[1]=s[5];
      s[5]=s[4];
      s[4]=b;
    }
    if(c==3){
      b=s[0];
      s[0]=s[4];
      s[4]=s[5];
      s[5]=s[1];
      s[1]=b;
    }
  }
  int top() { return s[0]; }
  int front() { return s[1]; }
  int bottom() { return s[5]; }
};

struct state{
	int z,y,x;
	int dir;
	Dice D;
	int nev;
	int ring;
	state(int nz,int ny,int nx,int ndir,int nnev,int rin){
		z=nz; y=ny; x=nx; dir=ndir;
		nev=nnev; ring=rin;
	}
};

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

string A[30][30];
int d[30][30][30][6][6][4][2];
int n;
int sy,sx,sz;
int gx,gy,gz;

bool NG(int z,int y,int x){
	if( z<0 || y<0 || x<0 || z>=n || y>=n || x>=n ) return 1;
	return 0;
}

bool WALL(int z,int y,int x){
	return A[z][y][x] == '#';
}

int rot(int dir,int A){
	if(dir%2==0) A++;
	A++;
	return (dir+A)%6;
}

bool get_ring(state S){
	return S.z==gz && S.y==gy && S.x==gx;
}

bool already(state S){
	//cerr<<S.z<<' '<<S.y<<' '<<S.x<<' '<<S.dir<<' '<<S.D.top()<<' '<<S.D.front()<<endl;
	return d[S.z][S.y][S.x][S.dir][S.D.top()][S.nev][S.ring]!=-1;
}
void SET(state P,state S){
	//if(P.nev && d[P.z][P.y][P.x][P.dir][P.D.top()][P.D.front()][P.nev][P.ring] <=2 )
	//	cerr<<P.ring<<' '<<P.nev<<' '<<P.z<<' '<<P.y<<' '<<P.x<<' '<<P.dir<<' '<<P.D.top()<<' '<<P.D.front()<<' '<<d[P.z][P.y][P.x][P.dir][P.D.top()][P.D.front()][P.nev][P.ring]<<endl;
	d[S.z][S.y][S.x][S.dir][S.D.top()][S.nev][S.ring] = d[P.z][P.y][P.x][P.dir][P.D.top()][P.nev][P.ring] +1;
}

state FORWARD(state B){
	B.x += dx[B.dir];
	B.y += dy[B.dir];
	B.z += dz[B.dir];
	return B;
}

void GO_DOWN(state &B){
	if( get_ring( B ) ) B.ring=1;
	B.x += DX[B.D.bottom()];
	B.y += DY[B.D.bottom()];
	B.z += DZ[B.D.bottom()];
	if( get_ring( B ) ) B.ring=1;
	//return B;
}

bool FALLEN(state S){
	if( S.nev != 0 ){
		int dir = S.D.bottom();
		//cerr<<dir<<endl;
		S.z += DZ[dir];
		S.y += DY[dir];
		S.x += DX[dir];
		if( NG(  S.z , S.y , S.x  ) ) return 0;
		if( WALL( S.z , S.y , S.x ) ) return 0;
	}
	else{
		r(i,6){
			int z = S.z + dz[i];
			int y = S.y + dy[i];
			int x = S.x + dx[i];
			if( NG( z , y , x ) ) continue;
			if( WALL( z , y , x ) ) return 0;
		}
	}

	return 1;
}

bool END(state &S){
	return S.z==sz && S.y==sy && S.x==sx && S.ring==1;
}

void solve(){
	queue<state>q;
	state S(sz,sy,sx,0,0,0);
	q.push(S);
	SET(S,S);
	while(!q.empty()){
		S = q.front(); q.pop();

		if( END(S) ) break;

		// 前進
		//cout<<S.z<<' '<<S.y<<' '<<S.x<<endl;
		{
			state B = FORWARD( S );
			if( !NG( B.z , B.y , B.x ) ){
				if( get_ring( B ) ) B.ring=1;
				if( !WALL( B.z , B.y , B.x ) ){
					while( FALLEN( B ) ) GO_DOWN( B );
					B.nev = max( B.nev-1 , 0 );
					if( !already( B ) ){
						SET( S , B );
						q.push(B);
					}
				}
			}
		}

		//目の位置
		{
			r(i,4){
				state B = S;
				B.dir = rot( B.dir , i );
				B.nev = max( B.nev-1 , 0 );
				if( !already( B ) ){
					SET( S , B );
					q.push(B);
				}
			}
		}

		//回転
		if(S.nev==0){
			r(i,4){
				state B = S;
				B.D.roll( i );
				while( FALLEN( B ) ) GO_DOWN( B );
				B.nev = max( B.nev-1 , 0 );
				if( !already( B ) ){
					SET( S , B );
					q.push(B);
				}
			}
		}

		//洗浄
		{
			state B = S;
			if( B.nev == 0 ){
				B.nev=3;
				while( FALLEN( B ) ) GO_DOWN( B );
				B.nev = max( B.nev-1 , 0 );
				if( !already( B ) ){
					SET( S , B );
					q.push(B);
				}
			}
		}

		//何もしない
		{
			state B = S;
			while( FALLEN( B ) ) GO_DOWN( B );
			B.nev = max( B.nev-1 , 0 );
			if( !already( B ) ){
				SET( S , B );
				q.push(B);
			}
		}

		//cout<<endl;

	}

	int answer = 114514;

	r(i,6){
		r(j,6){
			//r(k,6){
				r(l,4){
					if( d[sz][sy][sx][i][j][l][1] == -1 )continue;
					answer = min( answer , d[sz][sy][sx][i][j][l][1] );
				}
			//}
		}
	}

	cout<<( answer==114514?-1:answer )<<endl;

}

void init() {
	memset(d,-1,sizeof(d));
  cin>>n;
  string tmp;
  r(i,n){
  	r(j,n){
  		cin>>A[i][j];
  	}
  }
  r(i,n){
  	r(j,n){
  	  r(k,n){
	  	if(A[i][j][k]=='S'){
			sz=i;
			sy=j;
			sx=k;
	  	}
	  	if(A[i][j][k]=='R'){
			gz=i;
			gy=j;
			gx=k;
	  	}
	  }
  	}
  }
}

int main() {
  init();
  solve();
  return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 36236
final_rank: 7