U68364 _GC滑迷宫
题目背景
_GC买了一双蔡徐坤一代。
题目描述
_GC进入了一个n*m的迷宫。
本题的特殊之处在于,_GC只能滑着走。具体来说就是,选定一个方向后,_GC会一直向该方向滑,直到撞到墙。
会给出_GC的起始位置。只需要滑出去即可。
求最小的撞墙次数。
输入输出格式
输入格式:
第一行两个整数n,m表示迷宫大小。
下面n行,每行m个整数,0表示空地,1表示墙。
最后一行两个整数sx,sy表示_GC初始位置。
输出格式:
走出迷宫的最小撞墙次数。无解请输出-1。
输入输出样例
说明
1\leq n,m\leq 201≤n,m≤20 由于出题人太菜不会自动生成数据,数据都是手算的,可能有锅+很水
………………………………………………分割线~………………………………………………………
话说此题非常有趣啊,竟然是以我们的童鞋的大名为题......
好了进入正题:
既然是走迷宫的题目,那么此题应该就是一个搜索题,毋庸置疑吧。
但是和其他迷宫题不同的是:这个笨拙的_GC竟然要滑到墙上
那也好办,就比普通的迷宫题多了个步骤:只要前方没有障碍物,就让他一直滑下去,直到撞墙残忍,所用步数还是为1
int xx=h.x,yy=h.y; //记录这个点的位置 while(pd(xx+dx[i],yy+dy[i])) //如果这个方向没有障碍物,一直滑下去,pd是判断是否在迷宫内且当前方向的前方是否有障碍物 { xx+=dx[i]; yy+=dy[i]; }
解决完这个问题,就可以上代码啦:
#include<iostream> #include<cstdio> #include<cmath> #include<queue> using namespace std; int m,n,sx,sy; int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0}; //四个方向 bool a[25][25],vis[25][25]; //a数组存放迷宫,vis数组存放当前点是否到达过 struct pos //定义pos结构体,里面有横纵坐标及到达该点所撞墙的次数 { int x,y,step; pos(int x,int y,int step) : x(x),y(y),step(step){} //构造函数,意思是将括号里的值赋给外面的变量 }; queue<pos> q; //定义q队列,用到的头文件就是#include<queue> inline bool pd(int x,int y) //判断当前点是否在迷宫里且当前方向的前方是否有障碍物 { return x>=1&&x<=m&&y>=1&&y<=n&&a[x][y]==0; //如果为真,返回1;如果为假,返回0 } bool out(int x,int y) //判断_GC是否能滑出迷宫 { return (x==1||x==m||y==1||y==n)&&a[x][y]==0; } int main() { cin>>m>>n; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); cin>>sx>>sy; //起点坐标 if(a[sx][sy]==1) {cout<<-1;return 0;} //神奇的卡墙,判无解 if(out(sx,sy)==1) {cout<<0;return 0;} //如果本来就在出口,那么撞墙数为0 q.push(pos(sx,sy,0)); //将起点位置入队,并将坐标位置和撞墙次数赋值 vis[sx][sy]=1; //将起点位置标记为“1” while(!q.empty()) //判队列是否为空 { pos h=q.front(); //记录队首元素 q.pop(); //队首元素出队 if(out(h.x,h.y)==1) {cout<<h.step-1;return 0;} for(int i=0;i<4;i++) //四个方向 { int xx=h.x,yy=h.y; //记录这个点的位置 while(pd(xx+dx[i],yy+dy[i])) //如果这个方向没有障碍物,一直滑下去 { xx+=dx[i]; yy+=dy[i]; } if((xx==h.x&&yy==h.y)||vis[xx][yy]==1) continue; //如果位置没变或到达的位置已经遍历过,换方向 vis[xx][yy]=1; //将滑完后的点标记为 q.push(pos(xx,yy,h.step+1)); //将滑完后的位置入队 } } cout<<-1; //如果所有点都被遍历过且都为走出,则说明无解 return 0; }
蒟蒻刚学搜索,如果有错请诸位大佬们指出,谢谢qaq!