zoukankan      html  css  js  c++  java
  • 洛谷P1519 穿越栅栏 Overfencing

    P1519 穿越栅栏 Overfencing

      • 69通过
      • 275提交
    • 题目提供者该用户不存在
    • 标签USACO
    • 难度普及/提高-

      讨论  题解  

    最新讨论

    • USACO是100分,洛谷是20分
    • 为什么只有十分

    题目描述

    描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽度W(1<=W<=38)及高度H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,牛们只会水平或垂直地在X或Y轴上移动,他们从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:

    +-+-+-+-+-+

    | |

    +-+ +-+ + +

    | | | |

    • +-+-+ + +

    | | |

    +-+ +-+-+-+

    (请将上图复制到记事本观看更加)

    如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。

    输入输出格式

    输入格式:

    第一行: W和H(用空格隔开)

    第二行至第2 H + 1行: 每行2 W + 1个字符表示迷宫

    输出格式:

    输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。

    输入输出样例

    输入样例#1:
    5 3
    +-+-+-+-+-+
    |         |
    +-+ +-+ + +
    |     | | |
    + +-+-+ + +
    | |     |  
    +-+ +-+-+-+
    输出样例#1:
    9
    

    说明

    翻译来自NOCOW

    USACO 2.4

    分析:这道题的输入方式很奇怪啊,为啥非要用+来表示,这样的话,要把走一格变成走两格,总的来说就是BFS.

           先把图建出来,如果是空格就赋值为0,在边界处找到两个出口,加入到队列中,然后扩展节点,这样就可以只用从两个点扩展,而不必枚举一大堆点.

           要求的点要从最近的出口出来,那么从出口先扩展到的一定是离这个出口更近,访问到的点打上标记,这样就不会被第二个出口扩展的节点覆盖而使答案错误,在扩展节点的时候更新最大值即可.

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    
    using namespace std;
    int w, h,a[3110][3101],vis[3110][3101],ans;
    
    int ddx[5] = { 0,-1,1,0,0 };
    int ddy[5] = { 0,0,0,-1,1 };
    
    struct node
    {
        int x, y, step;
    };
    
    queue <node> q;
    
    int main()
    {
        scanf("%d%d
    ", &w, &h);
        w = w * 2 + 1;
        h = h * 2 + 1;
        for (int i = 1; i <= h; i++)
            for (int j = 1; j <= w; j++)
                a[i][j] = 1;
        
        for (int i = 1; i <= h; i++)
        {
            char s[500];
            cin.getline(s, 500);
            for (int j = 1; j <= w; j++)
                if (s[j - 1] != '+' && s[j - 1] != '-' && s[j - 1] != '|')
                    a[i][j] = 0;
        }
        /*
        for (int i = 1; i <= h; i++)
        {
            for (int j = 1; j <= w; j++)
                printf("%d", a[i][j]);
            printf("
    ");
        }
        */
        for (int i = 1; i <= h; i++)
            for (int j = 1; j <= w; j++)
                if (i == 1 || j == 1 || i == h || j == w)
                    if (a[i][j] == 0)
                    {
                        for (int k = 1; k <= 4; k++)
                        {
                            int tx = i + ddx[k], ty = j + ddy[k];
                            if (a[tx][ty] == 0 && tx >= 1 && tx <= h && ty >= 1 && ty <= w && vis[tx][ty] == 0)
                            {
                                node temp;
                                temp.x = tx;
                                temp.y = ty;
                                temp.step = 1;
                                q.push(temp);
                                vis[tx][ty] = 1;
                                break;
                            }
                        }
                    }
        ans = 1;
        while (!q.empty())
        {
            node t = q.front();
            q.pop();
            for (int k = 1; k <= 4; k++)
            {
                int tx = t.x + ddx[k], ty = t.y + ddy[k],tstep = t.step;
                if (a[tx][ty] == 0 && tx + ddx[k] <= h && tx + ddx[k] >= 1 && ty + ddy[k] <= w && ty + ddy[k] >= 1 && vis[tx + ddx[k]][ty + ddy[k]] == 0)
                {
                    node temp;
                    temp.x = tx + ddx[k];
                    temp.y = ty + ddy[k];
                    temp.step = tstep + 1;
                    vis[tx + ddx[k]][ty + ddy[k]] = 1;
                    q.push(temp);
                    //printf("%d %d %d
    ", temp.x, temp.y, temp.step);
                    if (temp.step > ans)
                        ans = temp.step;
                }
            }
        }
        printf("%d
    ", ans);
    
        //while (1);
        return 0;
    }
  • 相关阅读:
    认识ASP.NET 中的 AppDomain
    试验总结1 改变递归函数中的执行内容
    试验总结2 break与continue
    开篇的话
    01复杂度3 二分查找
    02线性结构2 一元多项式的乘法与加法运算
    01复杂度2 Maximum Subsequence Sum
    02线性结构4 Pop Sequence
    01复杂度1 最大子列和问题
    02线性结构1 两个有序链表序列的合并
  • 原文地址:https://www.cnblogs.com/zbtrs/p/5935020.html
Copyright © 2011-2022 走看看