**每日一题——魔鬼之城
—————————————我是分割线———————————————
题目解读
标准BFS或DFS,我是用BFS打的
可是题干中的这句话
因为这样他第二次跳跃的方向将和第一次相同,而这是不允许的>
导致我们在DFS或BFS时需要四个参
struct made{
int x;//横坐标
int y;//竖坐标
int t;//时间
int f;//上一次是从哪里过来的
};
queue<made> q;
可是与其他标准BFS不同的还有它可以向八个方向:上下左右,还有四条斜边。并且再每一个格子行走的距离必须是当前格子的值。如果剩余格子长度则不够无法行走。
—————————————我是分割线———————————————
思路诠述
使用一个三维数组
bool f[110][110][9]={};
第一维和第二维表示当前所在的点,第三维表示在八个方向走过没有;
如果走过则不能再走;
注意!!题目说这次走的方向不能和上次一样;
————————————我是分割线————————————————
代码展示
在这里插入#include<bits/stdc++.h>
using namespace std;
int a[110][110];
struct made{
int x;//横坐标
int y;//竖坐标
int t;//时间
int f;//上一次是从哪里过来的
};
bool f[110][110][9]={};
queue<made> q;//made 队列
int main()
{
int n,m;
scanf("%d%d",&m,&n);//**注意题目是先读列再读行**
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
q.push((made){1,1,0,0});//从第一行第一个各自开始,走了0步,上一次没有方向
while(!q.empty()){
int xx=q.front().x;
int yy=q.front().y;
int tt=q.front().t;
int ff=q.front().f;
// printf("ff== %d\n",ff);
q.pop();
if(xx==n&&yy==m){
printf("%d",tt);
return 0;
}
else{//八个方向搜索
// printf("xx== %d,yy== %d,tt== %d\n",xx,yy,tt);
if(xx-a[xx][yy]>=1&&xx-a[xx][yy]<=n&&yy>=1&&yy<=n&&f[xx][yy][1]==0&&ff!=1){
q.push((made){xx-a[xx][yy],yy,tt+1,1});
f[xx][yy][1]=1;//不能再走
}
if(yy-a[xx][yy]>=1&&yy-a[xx][yy]<=m&&xx>=1&&xx<=n&&f[xx][yy][7]==0&&ff!=7){
q.push((made){xx,yy-a[xx][yy],tt+1,7});
f[xx][yy][7]=1;//以下相同代码同上
}
if(xx+a[xx][yy]<=n&&xx+a[xx][yy]>=1&&yy<=m&&yy>=1&&f[xx][yy][5]==0&&ff!=5){
q.push((made){xx+a[xx][yy],yy,tt+1,5});
f[xx][yy][5]=1;
}
if(yy+a[xx][yy]<=m&&yy+a[xx][yy]>=1&&xx>=1&&xx<=n&&f[xx][yy][3]==0&&ff!=3){
q.push((made){xx,yy+a[xx][yy],tt+1,3});
f[xx][yy][3]=1;
}
if(xx+a[xx][yy]<=n&&xx+a[xx][yy]>=1&&yy+a[xx][yy]>=1&&yy+a[xx][yy]<=m&&f[xx][yy][4]==0&&ff!=4){
q.push((made){xx+a[xx][yy],yy+a[xx][yy],tt+1,4});
f[xx][yy][4]=1;
}
if(xx+a[xx][yy]<=n&&xx+a[xx][yy]>=1&&yy-a[xx][yy]>=1&&yy-a[xx][yy]<=m&&f[xx][yy][6]==0&&ff!=6){
q.push((made){xx+a[xx][yy],yy-a[xx][yy],tt+1,6});
f[xx][yy][6]=1;
}
if(xx-a[xx][yy]>=1&&xx-a[xx][yy]<=n&&yy-a[xx][yy]>=1&&yy-a[xx][yy]>=1&&f[xx][yy][2]==0&&ff!=2){
q.push((made){xx-a[xx][yy],yy-a[xx][yy],tt+1,2});
f[xx][yy][2]=1;
}
if(xx-a[xx][yy]>=1&&xx-a[xx][yy]<=n&&yy+a[xx][yy]<=m&&yy+a[xx][yy]>=1&&f[xx][yy][8]==0&&ff!=8){
q.push((made){xx-a[xx][yy],yy+a[xx][yy],tt+1,8});
f[xx][yy][8]=1;
}
}
}
printf("NEVER");
return 0;
}//完美结尾
——————————————我是分割线——————————————
反思
没有使用方向数组导致代码冗长;
读题不够完善;