1016.Cube on the Walk

6170 ワード

http://acm.timus.ru/problem.aspx?space=1&num=1016
考え方は簡単ですが、ややこしいです. 
つの立方体がすべての面を一定の順序で表すと、どのようにひっくり返しても全部で24の順序があります.  色を塗るなら  色が同じなら種類が少なくなります.
違う状態を表示したらspfaに一番短絡できます.
コード:
#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<map>

#include<vector>

#include<stack>

#include<set>

#include<map>

#include<queue>

#include<algorithm>

#include<cmath>

#define LL long long

#define sint short int

//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const int N=105;

const int INF=0x3f3f3f3f;

//typedef pair<int,int>point;

struct node

{

    int a[6];

}mem[N];

int I;

vector<int>vx,vy;

int dist[10][10][N];

bool in[10][10][N];

struct node1

{

    int x,y,k;

}f[10][10][N];

void upg(int a[],int b[])

{

    b[0]=a[4];b[1]=a[2];b[2]=a[0];

    b[3]=a[3];b[4]=a[1];b[5]=a[5];

}

void downg(int a[],int b[])

{

    b[0]=a[2];b[1]=a[4];b[2]=a[1];

    b[3]=a[3];b[4]=a[0];b[5]=a[5];

}

void leftg(int a[],int b[])

{

    b[0]=a[0];b[1]=a[1];b[2]=a[3];

    b[3]=a[4];b[4]=a[5];b[5]=a[2];

}

void rightg(int a[],int b[])

{

    b[0]=a[0];b[1]=a[1];b[2]=a[5];

    b[3]=a[2];b[4]=a[3];b[5]=a[4];

}

int add(int a[])

{

    for(int i=0;i<I;++i)

    {

        int j;

        for(j=0;j<6;++j)

        if(a[j]!=mem[i].a[j])

        break;

        if(j==6)

        {return i;}

    }

    for(int i=0;i<6;++i)

    mem[I].a[i]=a[i];

    ++I;

    return -1;

}

void dfs(int a[])

{

    int b[6];

    upg(a,b);

    if(add(b)==-1)

    dfs(b);

    downg(a,b);

    if(add(b)==-1)

    dfs(b);

    leftg(a,b);

    if(add(b)==-1)

    dfs(b);

    rightg(a,b);

    if(add(b)==-1)

    dfs(b);

}

int spfa(int x1,int y1,int k1,int nx,int ny)

{

    memset(dist,-1,sizeof(dist));

    memset(in,false,sizeof(in));

    queue<int>qtx,qty,qtk;

    qtx.push(x1);

    qty.push(y1);

    qtk.push(k1);

    dist[x1][y1][k1]=mem[k1].a[4];

    in[x1][y1][k1]=true;

    f[x1][y1][k1].x=-1;

    while(!qtx.empty())

    {

        int x2=qtx.front();qtx.pop();

        int y2=qty.front();qty.pop();

        int k2=qtk.front();qtk.pop();

        in[x2][y2][k2]=false;

        int b[6];

        if(y2<7)

        {

            upg(mem[k2].a,b);

            int k=add(b);

            if(dist[x2][y2+1][k]==-1||

               dist[x2][y2+1][k]>dist[x2][y2][k2]+mem[k].a[4])

               {

                   dist[x2][y2+1][k]=dist[x2][y2][k2]+mem[k].a[4];

                   f[x2][y2+1][k].x=x2;

                   f[x2][y2+1][k].y=y2;

                   f[x2][y2+1][k].k=k2;

                   if(!in[x2][y2+1][k])

                   {

                       in[x2][y2+1][k]=true;

                       qtx.push(x2);

                       qty.push(y2+1);

                       qtk.push(k);

                   }

               }

        }

        if(y2>0)

        {

            downg(mem[k2].a,b);

            int k=add(b);

            if(dist[x2][y2-1][k]==-1||

               dist[x2][y2-1][k]>dist[x2][y2][k2]+mem[k].a[4])

               {

                   dist[x2][y2-1][k]=dist[x2][y2][k2]+mem[k].a[4];

                   f[x2][y2-1][k].x=x2;

                   f[x2][y2-1][k].y=y2;

                   f[x2][y2-1][k].k=k2;

                   if(!in[x2][y2-1][k])

                   {

                       in[x2][y2-1][k]=true;

                       qtx.push(x2);

                       qty.push(y2-1);

                       qtk.push(k);

                   }

               }



        }

        if(x2>0)

        {

            leftg(mem[k2].a,b);

            int k=add(b);

            if(dist[x2-1][y2][k]==-1||

               dist[x2-1][y2][k]>dist[x2][y2][k2]+mem[k].a[4])

               {

                   dist[x2-1][y2][k]=dist[x2][y2][k2]+mem[k].a[4];

                   f[x2-1][y2][k].x=x2;

                   f[x2-1][y2][k].y=y2;

                   f[x2-1][y2][k].k=k2;

                   if(!in[x2-1][y2][k])

                   {

                       in[x2-1][y2][k]=true;

                       qtx.push(x2-1);

                       qty.push(y2);

                       qtk.push(k);

                   }

               }



        }

        if(x2<7)

        {

            rightg(mem[k2].a,b);

            int k=add(b);

            if(dist[x2+1][y2][k]==-1||

               dist[x2+1][y2][k]>dist[x2][y2][k2]+mem[k].a[4])

               {

                   dist[x2+1][y2][k]=dist[x2][y2][k2]+mem[k].a[4];

                   f[x2+1][y2][k].x=x2;

                   f[x2+1][y2][k].y=y2;

                   f[x2+1][y2][k].k=k2;

                   if(!in[x2+1][y2][k])

                   {

                       in[x2+1][y2][k]=true;

                       qtx.push(x2+1);

                       qty.push(y2);

                       qtk.push(k);

                   }

               }



        }

    }



    int nk=-1;

    for(int i=0;i<I;++i)

    {

        if((dist[nx][ny][i]!=-1)&&(nk==-1||dist[nx][ny][nk]>dist[nx][ny][i]))

        nk=i;

    }

    int sum=dist[nx][ny][nk];

    vx.clear();vy.clear();

    vx.push_back(nx);vy.push_back(ny);

    while(f[nx][ny][nk].x!=-1)

    {

        int pnx=f[nx][ny][nk].x;

        int pny=f[nx][ny][nk].y;

        int pnk=f[nx][ny][nk].k;

        nx=pnx;ny=pny;nk=pnk;

        vx.push_back(nx);vy.push_back(ny);

    }

    return sum;

}

int main()

{

    //freopen("data.in","r",stdin);

    char c1,c2;

    int x1,x2,y1,y2;

    cin>>c1>>y1;x1=c1-'a';--y1;

    cin>>c2>>y2;x2=c2-'a';--y2;

    int a[6];

    for(int i=0;i<6;++i)

    cin>>a[i];

    I=0;

    if(add(a)==-1)

    dfs(a);

    cout<<spfa(x1,y1,0,x2,y2);

    for(int i=vx.size()-1;i>=0;--i)

    printf(" %c%d",vx[i]+'a',vy[i]+1);

    cout<<endl;



}