记录编号 371518 评测结果 AAAAAAAAWW
题目名称 [CEPC 2003] 骰子游戏 最终得分 80
用户昵称 GravatarKZNS 是否通过 未通过
代码语言 C++ 运行时间 1.402 s
提交时间 2017-02-16 11:22:05 内存使用 0.34 MiB
显示代码纯文本
//KZNS
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef long long LL;
#define TPS 96
#define INF 1000000000000ll
class matrix {
    public:
        LL M[96][96];
    void i0() {
        memset(M, 0, sizeof(M));
    }
    void mx() {
        for (int i = 0; i < TPS; i++)
            for (int j = 0; j < TPS; j++)
                M[i][j] = INF;
    }
};
matrix operator * (matrix a, matrix b) {
    matrix c;
    c.i0();
    for (int i = 0; i < TPS; i++) {
        for (int j = 0; j < TPS; j++) {
            c.M[i][j] = INF;
            for (int k = 0; k < TPS; k++)
                c.M[i][j] = min(c.M[i][j], a.M[i][k] + b.M[k][j]);
        }
    }
    return c;
}
matrix fpw(int s, matrix a, int b) {
    matrix c;
    c.mx();
    for (int i = 0; i < TPS; i++)
        c.M[s][i] = a.M[s][i];
    b--;
    while (b) {
        if (b & 1)
            c = c * a;
        a = a * a;
        b >>= 1;
    }
    return c;
}
int V[6];//相比较于正常骰子,这里所有面的点数-1,则相对面的点数和为5 
int X0, Y0, X1, Y1, X;
int wls[6][4];//骰子上面为i时,相邻面第j大的点数 
int rls[6][6];
int cg[6][4][4][2];//上面为i,正面为第j大的相邻面时,向上右下左滚动后的上正面点数 
int dice[3] = {0, 1};//WSA骰子的上正左面 
matrix A;
namespace fir {
    void iDice() {//初始化骰子 
        if (X0 <= X1)
            dice[2] = 2;
        else
            dice[2] = 3;
        X = abs(X0 - X1);
        Y0--;
        Y1--;
    }
    void tA() {//向左滚 
        int u;
        u = 5 - dice[2];
        dice[2] = dice[0];
        dice[0] = u;
    }
    void tW() {//向上滚 
        int u;
        u = 5 - dice[0];
        dice[0] = dice[1];
        dice[1] = u;
    }
    void tQ() {//俯视,逆时针旋转骰子 
        int u;
        u = 5 - dice[1];
        dice[1] = dice[2];
        dice[2] = u;
    }
    void iCg() {
        int u; 
        for (int i = 0; i < 6; i++) {
            u = 0;
            for (int j = 0; j < 6; j++) {
                if (i == j || 5 - i == j)
                    continue;
                rls[i][j] = u;
                wls[i][u++] = j;
            }
        }
        for (int i = 0; i < 6; i++) {
            while (true) {
                tA();
                if (dice[0] == i)
                    break;
                tW();
                if (dice[0] == i)
                    break;
            }
            for (int j = 0; j < 4; j++) {
                while (dice[1] != wls[i][j])
                    tQ();
                cg[i][j][0][0] = dice[1];
				cg[i][j][0][1] = rls[dice[1]][5-dice[0]];
				
				cg[i][j][1][0] = dice[2];
				cg[i][j][1][1] = rls[dice[2]][dice[1]];
				
				cg[i][j][2][0] = 5-dice[1];
				cg[i][j][2][1] = rls[5-dice[2]][dice[0]];
				
				cg[i][j][3][0] = 5-dice[2];
				cg[i][j][3][1] = rls[5-dice[2]][dice[1]];
            }
        }
    }
    void init() {
        iDice();
        iCg();
    }
}
namespace mkA {
    class poi {
        public:
            int cost, x, y, w, s;
    };
    bool operator < (poi a, poi b) {
        return a.cost > b.cost;
    }
    inline int zip(int a, int b, int c) {
        return a*24 + b*4 + c;
    }
    int mv[4][2] = {
        {0, 1},
        {1, 0},
        {0, -1},
        {-1, 0}
    };
    bool ud[14][4][6][4];
    void kz(int y, int w, int s) {
        memset(ud, 0, sizeof(ud));
        priority_queue<poi> ls;
        int nu = TPS;
        int id = zip(y, w, s);
        ls.push((poi){0, 7, y, w, s});
        poi u;
        int x, cost;
        int xx, yy;
        while (!ls.empty() && nu) {
            u = ls.top();
            ls.pop();
            cost = u.cost;
            x = u.x;
            y = u.y;
            w = u.w;
            s = u.s;
            if (ud[x][y][w][s])
                continue;
            else {
                ud[x][y][w][s] = true;
                if (x == 8) {
                    A.M[id][zip(y, w, s)] = u.cost;
                    nu--;
                }
            }
            for (int i = 0; i < 4; i++) {
                xx = x + mv[i][0];
                yy = y + mv[i][1];
                if (0 <= xx && xx < 14 && 0 <= yy && yy < 4) {
                    u.cost = cost + V[cg[w][s][i][0]];
                    u.x = xx;
                    u.y = yy;
                    u.w = cg[w][s][i][0];
                    u.s = cg[w][s][i][1];
                    ls.push(u);
                }
            }
        }
    }
    void make() {
        A.mx();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 6; j++) {
                for (int k = 0; k < 4; k++) {
                    kz(i, j, k);
                }
            }
        }
    }
}
void init() {
    for (int i = 0; i < 6; i++)
        scanf("%d", &V[i]);
    scanf("%d %d %d %d", &X0, &Y0, &X1, &Y1);
    fir::init();
}
void ansit() {
    matrix C;
    int s, a, b;
    s = mkA::zip(Y0, 0, 0);
    a = mkA::zip(Y1, 0, 0);
    b = mkA::zip(Y1, 5, 3);
    C = fpw(s, A, X);
    LL ans = INF;
    for (int i = a; i <= b; i++)
        ans = min(ans, C.M[s][i]);
    printf("%lld\n", ans);
}
int main() {
    freopen("dicecontest.in", "r", stdin);
    freopen("dicecontest.out", "w", stdout);
    init();
    mkA::make();
    ansit();
    return 0;
}
//UBWH