【JZOJ4628】立方体

Description

这里写图片描述

Solution

首先注意数字行是从下到上的。

一个显然的结论是,我们如果确定了色子两个相邻面的位置,那么整个色子的状态就确定了。

于是我们很粗暴地手打一个表,打出每个状态往前往后往左往右的状态(这个有规律)。

然后我们设 Fi,j,k,l 表示当前坐标为 (i,j) ,状态为 (k,l) 的最小的总和。

于是在spfa中转移(其中 (i,j) 表示新坐标, (k,l) 表示新状态, p 表示朝下的那一面的编号):

Fi,j,k,l=min(Fi,j,k,l+ap)

只要有毅力就能AC!

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 9
#define M 100001
using namespace std;
char s1[4],s2[4];
int a[7];
int d[M][3];
int dl[M][3];
int fx[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int f[N][N][7][7];
bool bz[N][N][7][7];
int zh[201];
int db[4][7][7][2]=
{
    {
    {0},
    {{0},{0},{0},{4,3},{5,4},{6,5},{3,6}},
    {{0},{0},{0},{6,3},{3,4},{4,5},{5,6}},
    {{0},{6,1},{4,2},{0},{1,4},{0},{2,6}},
    {{0},{3,1},{5,2},{2,3},{0},{1,5},{0}},
    {{0},{4,1},{6,2},{0},{2,4},{0},{1,6}},
    {{0},{5,1},{3,2},{1,3},{0},{2,5},{0}}
    },
    {
    {0},
    {{0},{0},{0},{6,3},{3,4},{4,5},{5,6}},
    {{0},{0},{0},{4,3},{5,4},{6,5},{3,6}},
    {{0},{4,1},{6,2},{0},{2,4},{0},{1,6}},
    {{0},{5,1},{3,2},{1,3},{0},{2,5},{0}},
    {{0},{6,1},{4,2},{0},{1,4},{0},{2,6}},
    {{0},{3,1},{5,2},{2,3},{0},{1,5},{0}}
    },
    {
    {0},
    {{0},{0},{0},{3,2},{4,2},{5,2},{6,2}},
    {{0},{0},{0},{3,1},{4,1},{5,1},{6,1}},
    {{0},{1,5},{2,5},{0},{4,5},{0},{6,5}},
    {{0},{1,6},{2,6},{3,6},{0},{5,6},{0}},
    {{0},{1,3},{2,3},{0},{4,3},{0},{6,3}},
    {{0},{1,4},{2,4},{3,4},{0},{5,4},{0}}
    },
    {
    {0},
    {{0},{0},{0},{5,1},{6,1},{3,1},{4,1}},
    {{0},{0},{0},{5,2},{6,2},{3,2},{4,2}},
    {{0},{2,3},{1,3},{0},{6,3},{0},{4,3}},
    {{0},{2,4},{1,4},{5,4},{0},{3,4},{0}},
    {{0},{2,5},{1,5},{0},{6,5},{0},{4,5}},
    {{0},{2,6},{1,6},{5,6},{0},{3,6},{0}}
    },
};
int main()
{
    freopen("1.in","r",stdin);
    freopen("1.out","w",stdout);
    for(char i='a';i<='h';i++)
    zh[i]=i-'a'+1;
    int n;
    cin>>s1>>s2;
    int qdx=s1[1]-48,qdy=zh[s1[0]],zdx=s2[1]-48,zdy=zh[s2[0]];
    fo(i,1,6) scanf("%d",&a[i]);
    qdx=9-qdx;
    zdx=9-zdx;
    int l=0,r=1;
    memset(f,60,sizeof(f));
    d[1][1]=qdx;
    d[1][2]=qdy;
    dl[1][1]=5;
    dl[1][2]=1;
    f[qdx][qdy][5][1]=0;
    bz[qdx][qdy][5][1]=true;
    int ans=2147483647;
    while(l<r)
    {
        l++;
        int x=d[l][1],y=d[l][2];
        int p=dl[l][1],q=dl[l][2];
        fo(i,0,3)
        {
            int xx=x+fx[i][0],yy=y+fx[i][1];
            if(xx<1 || xx>8 || yy<1 || yy>8) continue;
            int pp=db[i][p][q][0],qq=db[i][p][q][1];
            if(f[xx][yy][pp][qq]>f[x][y][p][q]+a[pp])
            {
                f[xx][yy][pp][qq]=f[x][y][p][q]+a[pp];
                if(xx==zdx && yy==zdy)
                {
                    ans=min(ans,f[xx][yy][pp][qq]+a[5]);
                    continue;
                }
                if(!bz[xx][yy][pp][qq])
                {
                    r++;
                    d[r][1]=xx;
                    d[r][2]=yy;
                    dl[r][1]=pp;
                    dl[r][2]=qq;
                }
            }
        }
        bz[x][y][p][q]=false;
    }
    cout<<ans;
}
posted @ 2016-07-15 16:15  sadstone  阅读(43)  评论(0编辑  收藏  举报