D: Dice Room | JAG Asia 2010 (AOJ 2245)

f:id:parukii:20180523123925j:plain 出入り口に使う面の組、行の組(列の組)ごとに操作回数を考える。具体的には頭の中でサイコロを回転させつつ展開図に操作回数や行または列の対応を書き込んでいく。すると上のような図を得る。あとは最小値を計算するだけ。

// faceA, faceB, rowA, rowB, cost
int ROW_MAGIC[6][5] = {
{0,2,2,2,0},
{0,2,0,0,2},
{1,3,0,0,3},
{1,3,2,2,3},
{4,5,0,2,1},
{4,5,2,0,1}
};
// faceA, faceB, colA, colB, cost
int COL_MAGIC[6][5] = {
{0,2,0,2,1},
{0,2,2,0,1},
{1,3,0,2,2},
{1,3,2,0,2},
{4,5,0,0,2},
{4,5,2,2,2}
};

int main() {
    string S[6][3];
    const char E = '*';
    while (1) {
        rep(a, 6)rep(r, 3) {
            cin >> S[a][r];
            if (S[a][r] == "#")return 0;
        }
        int re = 9;
        rep(a,6){
            int fa, fb, ra, rb, d, oka=0,okb=0;
            int *p = ROW_MAGIC[a];
            fa = p[0], fb = p[1], ra = p[2], rb = p[3], d = p[4];
            rep(c, 3) {
                if (S[fa][ra][c] == E)oka = 1;
                if (S[fb][rb][c] == E)okb = 1;
            }
            if (oka&&okb)smin(re, d);
        }
        rep(a, 6) {
            int fa, fb, ca, cb, d, oka = 0, okb = 0;
            int *p = COL_MAGIC[a];
            fa = p[0], fb = p[1], ca = p[2], cb = p[3], d = p[4];
            rep(r, 3) {
                if (S[fa][r][ca] == E)oka = 1;
                if (S[fb][r][cb] == E)okb = 1;
            }
            if (oka&&okb)smin(re, d);
        }
        cout << re << endl;
    }
}