zoukankan      html  css  js  c++  java
  • [洛谷 U68862] 奶牛滑迷宫 题解

    说明:这原本是我很久之前出的一道题目。最近整理的时候发现这道题竟然还没写题解,就写了一下,顺便改&修了下题面。

    题目描述

    Farmer John的奶牛Besty进入了一个n*m的迷宫。

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

    会给出Besty的起始位置。只需要滑出去即可。

    求最小的撞墙次数。

    输入格式

    第一行两个整数n,m表示迷宫大小。

    下面n行,每行m个整数,0表示空地,1表示墙。

    最后一行两个整数sx,sy表示Besty初始位置。

    输出格式

    走出迷宫的最小撞墙次数。无解请输出-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
    

    输出

    3
    

    #2

    输入

    5 3
    1 1 1
    1 0 1
    0 0 1
    1 0 1
    1 1 1
    2 2
    

    输出

    -1
    

    数据范围

    共16个测试点。其中前13个保证(1leq n,mleq 30)。最后3个保证(1leq n,mleq 100)

    思路

    别看题面整了这么个花样,但他毕竟还是个迷宫问题。再看数据范围,直接搜索就完事。

    题解

    正常的迷宫问题是每次把相邻的格子作为新的状态去搜索。

    对于这道题目,我们也只需要从这个地方下手,把原本的搜索相邻格子变成搜索直到撞墙为止的格子即可。

    代码实现上,我们可以跑一个while循环并维护当前位置,如果下一个格子是墙那么退出循环并把当前位置作为新的状态;否则往前走一步(把当前位置设为下一个格子)

    代码

    这里仅给出BFS的实现。DFS实现同理,核心代码是一样的。

    #include <bits/stdc++.h>
    using namespace std;
    int n, m, sx, sy;
    bool mat[501][501];
    const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
    struct pos
    {
        int x, y, step;
        pos(int x, int y, int step) : x(x), y(y), step(step) {}
    };
    queue<pos> q;
    bool vis[501][501];
    inline bool pan(int x, int y)
    {
        return x >= 1 && x <= n && y >= 1 && y <= m && mat[x][y] == 0;
    }
    bool out(int x, int y)
    {
        return (x == 1 || x == n || y == 1 || y == m) && mat[x][y] == 0;
    }
    int main()
    {
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                cin >> mat[i][j];
            }
        }
        cin >> sx >> sy;
        if(mat[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();
            q.pop();
            // cout << h.x << ' ' << h.y << endl;
            if (out(h.x, h.y))
            {
                cout << h.step - 1;
                return 0;
            }
            for (int i = 0; i < 4; i++)
            {
                int xx = h.x, yy = h.y;
                while (pan(xx + dx[i], yy + dy[i]))
                {
                    xx += dx[i];
                    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;
    }
    
  • 相关阅读:
    掌控像素的虚实
    多用组合,少用继承
    HTML5的语法变化和新增加元素
    又逢六月
    设计心情之心情设计
    web2.0生成器(超过100个)[转]
    css+div CSS教程——元素定位
    项目进度
    清华大学统一认证接口与PHP的调用
    将51JOB的求职意向选择框Down了
  • 原文地址:https://www.cnblogs.com/water-lift/p/12860576.html
Copyright © 2011-2022 走看看