U68364 _GC滑迷宫

U68364 _GC滑迷宫

       本题的特殊之处在于,_GC只能滑着走。具体来说就是,选定一个方向后,_GC会一直向该方向滑,直到撞到墙。

 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue> 
#include <bits/stdc++.h>
using namespace std;
int n,m,sx,sy; 
int dx[4]={-1,1,0,0},
    dy[4]={0,0,-1,1};
bool bz[501][501];
bool vis[501][501];
struct pos
{
    int x,y,step;
    pos(int xx,int yy,int stepp) : x(xx),y(yy),step(stepp) {}   
//构造函数,把xx赋值给x(后边也是); }; queue
<pos> q; //定义一个pos类型的队列q bool pan(int x,int y) //判断合法性(防止出现_GC卡在墙里) { return x>=1&&x<=n&&y>=1&&y<=m&&bz[x][y]==0; } bool out(int x,int y) //判断是否已到达迷宫边界,即可以离开迷宫 { return (x==1||x==n||y==1||y==m)&&bz[x][y]==0; } int main() { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>bz[i][j]; cin>>sx>>sy; if(bz[sx][sy]) //如果初始位置是墙,则无解 { cout<<"-1"; return 0; } if(out(sx,sy)) //如果初始位置在边界,则直接离开 { cout<<"0"; return 0; } q.push(pos(sx,sy,0)); //入队 vis[sx][sy]=1; //标记已经走过 while(!q.empty()) //队列非空 { pos h=q.front(); //把队首元素的三个值全部赋值给h q.pop(); //队首出队 if(out(h.x,h.y)) //如果到达出口 { cout<<h.step-1; //因为原题求的是撞墙次数,而我们知道最后一次是不撞墙的 return 0; //直接退出,因为已求得最优解 } for(int i=0;i<=3;i++) { int xx=h.x,yy=h.y; while(pan(xx+dx[i],yy+dy[i])) //如果没撞到墙,就继续走 { xx+=dx[i]; //_GC要一直滑啊滑 yy+=dy[i]; //滑啊滑 } if((xx==h.x&&yy==h.y)||vis[xx][yy]) //如果并没有移动,或者最终位置已到达过 continue; vis[xx][yy]=1; q.push(pos(xx,yy,h.step+1)); } } cout<<-1; //如果所有可能节点都已遍历,而始终没有到达边界,则无解 }

 

posted @ 2019-04-14 16:26  晔子  阅读(285)  评论(3编辑  收藏  举报