骰子
骰子
【问题描述】
一个
其中,
大小和迷宫的每个小格的大小相同。骰子可以在迷宫的棋盘上翻动到相邻的格子。但是不能翻出迷宫的边界。
你的任务是找到一条通路,使得骰子能从迷宫的左上角翻到右下角,且到达目的地时的上侧面上的数值最大。骰子可以经过同一个格子若干次。
【数据输入】
第一行有两个整数
【数据输出】
第一行一个整数
PS:由于搜索路径不唯一,所以规定搜索顺序为右→下→左→上
【样例输入】
3 2
0 1
0 0
0 0
【样例输出】
3
2 1
2 2
3 2
【数据范围】
对于
对于
Solution
就是一个广度优先搜索,只是标记入队状态很难标记。
学过小学数学的都知道, 一个骰子的前面、上面、左面知道了,整个骰子的形态就确定了(因为任何一个面与背面的点数加起来为7)
不多说,直接上代码。
code:
#include<cstdio>
#include<queue>
#define N 50
#define M 50
using namespace std;
struct qianqu{
int x,y;
}pre[N+10][N+10];
struct node{
int x,y,top,left,front,step;
};
queue<node>q;
int n,m,map[N+10][M+10],fx[4]={0,1,0,-1},fy[4]={1,0,-1,0},ans=-1,ans_step;
bool vis[N+10][N+10][7][7];/*vis[x][y][a][b]表示坐标为x,y的点上侧面为a,左侧面为b的情况
是否被搜索过*/
int next_top(int top,int left,int front,int f)
{
if(f==0)return left;
if(f==1)return 7-front;
if(f==2)return 7-left;
if(f==3)return front;
}
int next_left(int top,int left,int front,int f)
{
if(f==0)return 7-top;
if(f==1)return left;
if(f==2)return top;
if(f==3)return left;
}
int next_front(int top,int left,int front,int f)
{
if(f==0)return front;
if(f==1)return top;
if(f==2)return front;
if(f==3)return 7-top;
}
void print(int x,int y)
{
if(x==1&&y==1)return;
print(pre[x][y].x,pre[x][y].y);
printf("%d %d\n",x,y);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&map[i][j]);
q.push((node){1,1,1,2,4,0});
vis[1][1][1][2]=1;
node temp;int dx,dy,dfront,dtop,dleft;
while(!q.empty())
{
temp=q.front();q.pop();
for(int i=0;i<=3;i++)
{
dx=temp.x+fx[i];dy=temp.y+fy[i];
dleft=next_left(temp.top,temp.left,temp.front,i);
dtop=next_top(temp.top,temp.left,temp.front,i);
dfront=next_front(temp.top,temp.left,temp.front,i);
if(dx<1||dx>n||dy<1||dy>m)continue;//边界
if(dx==n&&dy==m)//到终点
{
if(ans<=dtop)
{
if(ans<dtop){
pre[n][m].x=temp.x;pre[n][m].y=temp.y;
ans=dtop;ans_step=temp.step+1;
/*printf("%d %d\n",ans_step,ans);
print(n,m);*/
}
if(ans==dtop&&ans_step>temp.step+1)//更新路径长度
{
pre[n][m].x=temp.x;pre[n][m].y=temp.y;
ans_step=temp.step+1;
}
}
continue;//一定要跳过终点,否则pre数组会形成环,然后报错
}
if(!vis[dx][dy][dtop][dleft]&&map[dx][dy]==0)//能走
{
vis[dx][dy][dtop][dleft]=1;
pre[dx][dy].x=temp.x;pre[dx][dy].y=temp.y;
q.push((node){dx,dy,dtop,dleft,dfront,temp.step+1});
}
}
}
if(ans==-1)printf("%d",ans);
else
{
printf("%d\n",ans_step);
print(n,m);
}
return 0;
}