这题有点坑,给的标准展开图中3和4的位置弄反了。
除了这个地方之外,只能说自己太笨了,这个题目已经明显提示一个骰子两个面足够确定骰子是唯一的。
所以状态就是坐标+顶面数字+前面数字。总共最多为row*column*24.
状态转移是四。很快就可以解出。
#include <set> #include <queue> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; const int maxn = 11; int L[7][4]={ {0},{3,2,4,5}, {1,3,6,4}, {1,5,6,2}, {1,2,6,5}, {1,4,6,3}, {3,5,4,2} }; int to(int u,int f){ for(int i=0;i<4;i++){ if(L[u][i]==f) return L[u][(i+1)%4]; } } int vis[maxn][maxn][7][7]; void rotate(int& u,int& f,int d){ if(d==0){int tmp=u; u=f; f=7-tmp;} if(d==1){u=to(u,f);} if(d==2){int tmp=f; f=u; u=7-tmp;} if(d==3){u=7-to(u,f);} } struct node{ int x,y,u,f; int pre; node(int x=0,int y=0,int u=0,int f=0,int pre=0): x(x),y(y),u(u),f(f),pre(pre){} }; node sta[24*maxn*maxn]; int sx,sy,u,f,maze[maxn][maxn],n,m; vector<node> ans; void print_ans(int F){ //cout<<F<<endl; ans.clear(); ans.push_back(node(sx,sy,0,0,0)); while(F!=-1){ ans.push_back(sta[F]); F=sta[F].pre; } for(int j=ans.size()-1,i=0;j>=0;i++,j--){ if(i%9==0) printf(" "); printf("(%d,%d)",ans[j].x,ans[j].y); if(i!=ans.size()-1) printf(","); if((i+1)%9==0||i==ans.size()-1) printf("\n"); } } bool bfs(){ sta[0]=node(sx,sy,u,f,-1); memset(vis,0,sizeof(vis)); int front_=0,rear=1; while(front_<rear){ node& u=sta[front_]; for(int d=0;d<4;d++){ int nx=u.x+dx[d],ny=u.y+dy[d]; if(!(nx>=0&&ny>=0&&nx<=n&&ny<=m)) continue; if(maze[nx][ny]!=-1&&maze[nx][ny]!=u.u) continue; if(nx==sx&&ny==sy){ print_ans(front_); return true; } node v=u; v.x=nx; v.y=ny; rotate(v.u,v.f,d); if(!vis[v.x][v.y][v.u][v.f]){ vis[v.x][v.y][v.u][v.f]=1; v.pre = front_; sta[rear++]=v; } } front_++; } return false; } char name[1000]; int main() { while(scanf("%s",name)!=EOF&&strcmp("END",name)!=0){ scanf("%d %d %d %d %d %d",&n,&m,&sx,&sy,&u,&f); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&maze[i][j]); printf("%s\n",name); if(!bfs()) printf(" No Solution Possible\n"); } }