Poj2618 Cube in Labyrinth (广搜 状态扩展)

题目链接:http://poj.org/problem?id=2618

 

题意:矩形平面可以分成n*m个单位小正方形,在这个平面上的某位置处放置一棱长等于小正方形的立方体,它可以沿与平面接触的棱在平面上上下左右翻转进入一下相邻方格,某些方格之间有墙,不能在它们之间翻转,求立方体从某一位置进行翻转移动,到另外一个位置并且向上的平面不变的情况下的最小步数.

 

挺的意思的一道题,可以用广搜来解决,首先,必需明确的是状态转移之间除了位置的不同外,还有立文体放置方式的不同,在某一们置上,小立方体共有24种放置情况,所以可以增加一维来表示到达该点时立方体的放置情况,则标记数组为vis[M][M][24];另外,立方体的放置情况可以用其三个面来表示,翻转时改变三个面的值即可.

 

代码:

#include<stdio.h> #include<string.h> #include<queue> using namespace std; #define M 16 #define UP 0 #define DOWN 1 #define LEFT 2 #define RIGHT 3 typedef struct talP{ short x,y; bool operator == (const talP &a)const {return a.x==x&&a.y==y;} }Point; typedef struct talC{ short face,up,left; talC(){} talC(int f,int u,int l):face(f),up(u),left(l){} void Set(int f,int u,int l) {face=f;up=u;left=l;} void Turn(short i){ short tmp; switch(i){ case UP:tmp=face,face=5-up,up=tmp;break; case DOWN:tmp=up,up=5-face,face=tmp;break; case LEFT:tmp=face,face=5-left,left=tmp;break; case RIGHT:tmp=left,left=5-face,face=tmp; } } bool operator == (const talC &a) const {return a.face==face;} }Cube; typedef struct talN{ Point p; Cube c; int t; bool operator == (const talN &a) const {return a.p==p&&a.c==c;} }Node; bool map[M][M][4]; bool vis[M][M][24]; bool matrix[6][6]; int dir[][2]={{-1,0},{1,0},{0,-1},{0,1}}; int r,c; queue<Node>q; Node start,end; void InitMat() { short i,j; for(i=0;i<6;i++){ for(j=0;j<6;j++) matrix[i][j]=i!=j&&i+j!=5; } } short GetValue(Cube cc) { short c=0,k,i,j; i=cc.face;j=cc.up; for(k=0;k<j;k++) c+=matrix[i][k]; return i*4+c; } int BFS() { Node cur,next; int x,y,i; vis[start.p.x][start.p.y][GetValue(start.c)]=true; q.push(start); while(!q.empty()){ cur=q.front();q.pop(); if(cur==end) return cur.t; next.t=cur.t+1; for(i=0;i<4;i++){ if(map[cur.p.x][cur.p.y][i]) continue; x=cur.p.x+dir[i][0]; y=cur.p.y+dir[i][1]; if(x<1||x>r||y<1||y>c) continue; next.p.x=x;next.p.y=y; next.c=cur.c; next.c.Turn(i); if(vis[next.p.x][next.p.y][GetValue(next.c)]) continue; vis[next.p.x][next.p.y][GetValue(next.c)]=true; q.push(next); } } return -1; } int main() { char s[64],*p; int ans,x,y,flag=1; //freopen("put6.in","r",stdin); InitMat(); scanf("%d%d",&r,&c); scanf("%d%d",&start.p.x,&start.p.y); scanf("%d%d",&end.p.x,&end.p.y); getchar(); while(gets(s)){ if(s[0]=='v'){ flag=1;continue;} if(s[0]=='h'){ flag=2;continue;} p=strchr(s,' ');*p=0,p++; x=atoi(s);y=atoi(p); switch(flag){ case 1:map[x][y][DOWN]=true,map[x+1][y][UP]=true;break; case 2:map[x][y][RIGHT]=true,map[x][y+1][LEFT]=true; } } start.c.Set(0,1,2); end.c.Set(0,1,2); start.t=end.t=0; ans=BFS(); printf(ans!=-1?"%d/n":"no/n",ans); return 0; } 

你可能感兴趣的:(Poj2618 Cube in Labyrinth (广搜 状态扩展))