• 洪水


    【题目描述】

    CCY所在的城市可以用一个N*M(N,M <= 50)的地图表示,地图上有五种符号:“. * X D S”。其中,“X”表示石头,水和人都不能从上面经过,“.”表示平原,CCY和洪水都可以经过,“*”表示洪水开始的地方(可能有多个地方同时开始发生洪水),“D”表示CCY的别墅,“S”表示CCY现在的位置。

    CCY每分钟可以向相邻位置移动,而洪水将会在CCY移动之后把相邻的没有洪水的土地淹没(从已淹没的土地)。

    先询问CCY回到别墅的最少时间。

    【输入描述】

    第一行输入两个整数N和M(N,M <= 50);

    接下来输入一个N*M的字符矩阵,表示CCY所在城市的地图。

    【输出描述】

    输出一个整数,表示CCY回到别墅需要的最少时间,如果无解,输出-1。

    【输入样例】

    3 3

    D.*

    ...

    .S.

    【输出样例】

    3

    【数据范围及提示】

    先BFS出每个点被水淹没的时间,然后再次BFS。

    源代码:
    
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    queue <int> Q;
    int x[4]={0,0,1,-1};
    int y[4]={1,-1,0,0};
    int m,n,End1,End2,Start1,Start2,i[51][51];
    int main() //细节巨多的BFS题,做搜索还得三思而后行。
    {
        memset(i,0x3f,sizeof(i));
        scanf("%d%d
    ",&n,&m);
        for (int a=1;a<=n;a++)
        {
            char S[51];
            scanf("%s",S+1); //看来NOIP字符串输入就靠它了。
            for (int b=1;b<=m;b++)
            {
                if (S[b]=='D')
                {
                    End1=a;
                    End2=b;
                    i[a][b]=0; //洪水无法到达的标记。
                }
                if (S[b]=='S')
                {
                    Start1=a;
                    Start2=b;
                }
                if (S[b]=='X')
                  i[a][b]=0;
                if (S[b]=='*')
                {
                    i[a][b]=0;
                    Q.push(a);
                    Q.push(b);
                }
            }
        }
        while (!Q.empty())
        {
            int X=Q.front(); //新奇的队列用法,值得学习。
            Q.pop();
            int Y=Q.front();
            Q.pop();
            for (int a=0;a<4;a++)
            {
                int t1=X+x[a];
                int t2=Y+y[a];
                if (!t1||!t2||t1>n||t2>m||i[t1][t2]!=i[0][0]) //不能走的。
                  continue;
                i[t1][t2]=i[X][Y]+1;
                Q.push(t1);
                Q.push(t2);
            }
        }
        Q.push(0);
        Q.push(Start1);
        Q.push(Start2);
        while (!Q.empty())
        {
            int t=Q.front();
            Q.pop();
            int X=Q.front();
            Q.pop();
            int Y=Q.front();
            Q.pop();
            for (int a=0;a<4;a++)
            {
                int t1=X+x[a];
                int t2=Y+y[a];
                if (t1==End1&&t2==End2)
                {
                    printf("%d",t+1);
                    return 0;
                }
                if (!t1||!t2||t1>n||t2>m||i[t1][t2]<=t+1) //走过了或者洪水早已没过。
                  continue;
                i[t1][t2]=0; //先到就是最优,直接标记不能返回。
                Q.push(t+1);
                Q.push(t1);
                Q.push(t2);
            }
        }
        printf("ORZ hzwer!!!");
        return 0;
    }
  • 相关阅读:
    python常见排序算法解析
    分析python日志重复输出问题
    Mysql数据库基础
    横屏竖屏
    禁止iOS的弹性滚动 微信的下拉回弹
    移动性能
    取消双击上滑(针对iso)
    关于微信端 顶部会撑开页面的解决方案
    CSS动画简介
    browser-sync 使用简介
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5448275.html
Copyright © 2020-2023  润新知