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;

}

  

 

posted on 2013-01-20 16:33  夜->  阅读(180)  评论(0编辑  收藏  举报