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; }