• U68364 _GC滑迷宫


    题目背景

    _GC买了一双蔡徐坤一代。

    题目描述

    _GC进入了一个n*m的迷宫。
    本题的特殊之处在于,_GC只能滑着走。具体来说就是,选定一个方向后,_GC会一直向该方向滑,直到撞到墙。
    会给出_GC的起始位置。只需要滑出去即可。
    求最小的撞墙次数。

    输入输出格式

    输入格式:

    第一行两个整数n,m表示迷宫大小。
    下面n行,每行m个整数,0表示空地,1表示墙。
    最后一行两个整数sx,sy表示_GC初始位置。

    输出格式:

    走出迷宫的最小撞墙次数。无解请输出-1。

    输入输出样例

    输入样例#1: 复制
    5 6
    1 1 1 1 1 0
    1 0 1 0 0 0
    1 0 0 1 0 1
    1 0 0 0 0 1
    1 1 0 0 1 1
    2 2
    输出样例#1: 复制
    3
    输入样例#2: 复制
    5 3
    1 1 1
    1 0 1
    0 0 1
    1 0 1
    1 1 1
    2 2
    输出样例#2: 复制
    -1

    说明

    1leq n,mleq 201n,m20 由于出题人太菜不会自动生成数据,数据都是手算的,可能有锅+很水

    ………………………………………………分割线~………………………………………………………

    话说此题非常有趣啊,竟然是以我们的童鞋的大名为题......

    好了进入正题:

    既然是走迷宫的题目,那么此题应该就是一个搜索题,毋庸置疑吧。

    但是和其他迷宫题不同的是:这个笨拙_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!

  • 相关阅读:
    报错:Table 'sell.hibernate_sequence' doesn't exist
    “可恶”的mariadb
    日志的使用
    微信小程序开发步骤简述
    我对同步异步阻塞和非阻塞的简单理解
    dubbo+zookeeper搭建时报错java.lang.NoClassDefFoundError: org/apache/curator/RetryPolicy
    在CentOS7中安装zookeeper
    markdown 显示图片的三种方式
    Spring Data JPA 提供的各种Repository接口作用
    windows nginx 搭建文件服务器(通俗易懂)
  • 原文地址:https://www.cnblogs.com/xcg123/p/10705645.html
Copyright © 2020-2023  润新知