2578: Moving Dice
Result |
TIME Limit |
MEMORY Limit |
Run Times |
AC Times |
JUDGE |
|
5s |
65536K |
235 |
46 |
Standard |
小明觉得自己的空间想象力不错,但是在玩这个游戏的时候,小明遇到了困难。游戏是这样的,有一个n*m的棋盘和一个骰子(正方体,每个面有一个不同的数字,1~6),骰子一个面的大小恰好能覆盖住棋盘的一个格子。游戏开始的时候骰子放在棋盘的某一个格子里,骰子可以以他的楞为轴向上下左右四个方向滚动,当骰子以各面特定的朝向(比如左侧面是数字4,底面是数字6)到达目标位置时,游戏结束。小明的问题是,骰子至少要滚动多少次,游戏才可以结束。请你帮帮小明。
小明用的骰子的展开图如下右图。左,右侧面平行于棋盘长度为n的边,前后面平行于棋盘长度为m的边,底面是和棋盘接触的面。 你可以认为,初始和结束状态时,骰子的状态(各面数字以及相对位置),是该骰子可以通过旋转达到的。
Input
多case,每个case三行。第一行是两个整数n,m,(1<=n,m<=100)表示棋盘的大小,第二行八个整数,前两个数字sx,sy表示游戏开始时骰子在棋盘上的位置(1<=sx<=n,1<=sy<=m),接下来的六个数字,依次是骰子在初始位置时,上,下,左,右,前,后,各面的数字。第三行八个整数,前两个数字ex,ey表示目标位置(1<=ex<=n,1<=ey<=m),接下来的六个数字,依次是要求骰子到达该位置时,上,下,左,右,前,后,各面的数字。
Output
每个case一行,一个整数,表示骰子最少滚动几次,如果不能到达输出-1。
Sample Input
2 2
1 1 1 6 4 3 2 5
1 2 4 3 6 1 2 5
2 2
1 1 1 6 4 3 2 5
1 1 4 3 5 2 6 1
Sample Output
1
4
Hint:Case 1骰子向右滚动一次,Case 2骰子依次向右,下,左,上进行一次滚动。
This problem is used for contest: 132 149 185
Submit / Problem List / Status / Discuss
这个一个比较繁琐的跨度优先搜索的一个题。首先必须得知道一个筛子当两个相邻的面确定之后
那么这个筛子的状态就完全确定了,因为筛子的长宽高已经确定了。比较复杂的是找出每种情况
的状态,并且需要找到这些点移动之后点的状态,因为只需要知道两个面的状态就可以因此在考虑
时候需要将24种情况一块考虑,如果往上移就全往上移。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int n,m;
int origin[10];
int destination[10];
int originx,originy,destinationx,destinationy;
bool ok;
int state[100];
int move[27][4]={{0,0,0,0,},
{32,51,42,26},{53,41,23,36},{24,31,54,46},{45,21,35,56},
{41,62,31,15},{13,42,63,35},{64,32,14,45},{36,12,46,65},
{21,63,51,14},{62,53,12,24},{15,23,65,54},{56,13,26,64},
{51,64,21,13},{12,54,62,23},{65,24,15,53},{26,14,56,63},
{31,65,41,12},{63,45,13,32},{14,35,64,42},{46,15,36,62},
{42,56,32,21},{23,46,53,31},{54,36,24,41},{35,26,45,51}
};
int shift[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int visited[105][105][100];
void init()
{
for(int i=0;i<=n+1;i++)
{
for(int j=0;j<=m+1;j++)
{
for(int k=0;k<=100;k++)
visited[i][j][k]=0;
}
}
state[12]=1;state[13]=2;state[14]=3;state[15]=4;
state[21]=5;state[23]=6;state[24]=7;state[26]=8;
state[31]=9;state[32]=10;state[35]=11;state[36]=12;
state[41]=13;state[42]=14;state[45]=15;state[46]=16;
state[51]=17;state[53]=18;state[54]=19;state[56]=20;
state[62]=21;state[63]=22;state[64]=23;state[65]=24;
}
class Node
{
public:
int x,y;
int step;
int value;
};
void bfs()
{
Node node,temp;
queue<Node>q;
node.x=originx;
node.y=originy;
node.step=0;
node.value=origin[1]*10+origin[3];
q.push(node);
visited[node.x][node.y][node.value]=1;
//printf("%d %d %d %d\n",node.x,node.y,node.value,node.step);
while(!q.empty())
{
temp=q.front();
q.pop();
if(temp.x==destinationx&&temp.y==destinationy)
{
int ss=destination[1]*10+destination[3];
if(ss==temp.value)
{
printf("%d\n",temp.step);
ok=false;
return ;
}
}
node=temp;
for(int i=0;i<4;i++)
{
temp=node;
temp.x=node.x+shift[i][0];
temp.y=node.y+shift[i][1];
temp.value=move[state[node.value]][i];
if(temp.x>=1&&temp.x<=n&&temp.y>=1&&temp.y<=m&&
!visited[temp.x][temp.y][temp.value])
{
visited[temp.x][temp.y][temp.value]=1;
temp.step=node.step+1;
// printf("%d %d %d %d\n",temp.x,temp.y,temp.value,temp.step);
q.push(temp);
//printf("hello\n");
}
}
}
}
int main()
{
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&m)==2)
{
ok=true;
scanf("%d%d",&originx,&originy);
for(int i=1;i<=6;i++)scanf("%d",&origin[i]);
scanf("%d%d",&destinationx,&destinationy);
for(int i=1;i<=6;i++)scanf("%d",&destination[i]);
init();
bfs();
if(ok)printf("-1\n");
}
return 0;
}