• CF1063B Labyrinth


    题目大意:

    一个(n)行,(m)列的迷宫,('.')表示空地, ('*')表示障碍,可以向上下左右移动,但是左右移动时会有步数限制,求所能到达的格子数。(原题链接:Labyrinth

    输入格式:

    第一行:(n), (m),表示迷宫行数和列数
    第二行:(r), (c), 表示起点
    第三行:(x), (y), 表示向左向右移动的最大步数

    输出格式:

    一个数:所能到达的格子数(res)

    样例:

    输入 (1.)
    4 5
    3 2
    1 2
    .....
    .*.
    ...

    *...
    输出 (1.)
    10

    思路:

    CF重思维真不是瞎说的,这道题一看完全没有思路~~
    去官网翻了一下原题题解大体是这样:由于这题有向左最大步数向右最大步数两个限制,因此有点麻烦,但是我们可以发现一个限制:

    向左走的步数 - 向右走的步数 = 起点横坐标 - 终点横坐标

    因此我们就可以把它转化为一个限制啦,因为可以根据这个式子就可以由向左走的步数同时表示向右走的步数。因此我们只需要求出向左走的(01)最短路即可(可以用(spfa)来解决)。
    最后计算答案时满足 向左步数 <= 向左最大步数 && 向左步数 + 横坐标之差 <= 最大向右步数 就计入答案。

    还有这个只求向左走的最短路也是刚学到dist[xx][yy] > dist[t.first][t.second] + (i == 3) ···

    代码:

    #include <iostream>
    #include <queue>
    #include <cstring>
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    typedef pair<int, int> PII;
    
    const int N = 2010;
    
    int n, m, r, c, x, y;
    char mp[N][N];
    bool vis[N][N];
    int dist[N][N];
    int res;
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    
    void bfs(int x, int y)
    {
        queue<PII> q;
        memset(dist, 0x3f, sizeof dist);
        q.push({x, y});
        vis[x][y] = true;
        dist[x][y] = 0;
    
        while(q.size())
        {
            auto t = q.front();
            q.pop();
            vis[t.first][t.second] = false;
            for(int i = 0; i < 4; i++)
            {
                int xx = t.first + dx[i], yy = t.second + dy[i];
                if(mp[xx][yy] == '.' && dist[xx][yy] > dist[t.first][t.second] + (i == 3))
                {
                    dist[xx][yy] = dist[t.first][t.second] + (i == 3);
                    if(!vis[xx][yy])
                    {
                        vis[xx][yy] = true;
                        q.push({xx, yy});
                    }
                }
            }
        }
        
    }
    
    int main()                        
    {
        cin >> n >> m >> r >> c >> x >> y;
        for(int i = 1;  i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                cin >> mp[i][j];
            }
        }
        
        bfs(r, c);
    
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                if(mp[i][j] == '.' && dist[i][j] <= x && dist[i][j] + j - c <= y) res++;
            }
        }
    
        cout << res << endl;
    
        return 0;
    } 
    
  • 相关阅读:
    串口调试助手的源码分析,子对话框部分
    vc 使用了SerialPort类的串口通信软件分析
    Web前端研发工程师编程能力飞升之路
    vc mscomm串口通信使用了CButtonST按钮类软件分析
    vc 串口精灵软件分析
    c#串口完全接收程序
    Windows Server 2003操作系统中禁用Internet Explorer增强的安全特性
    Window下查看进程端口号
    面向对象的设计原则(2)——依赖注入
    面向对象的设计原则(1)
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/13578167.html
Copyright © 2020-2023  润新知