• bfs


    题目描述

    链接地址:http://bailian.openjudge.cn/practice/4129/
    4129:变换的迷宫
    总时间限制: 1000ms 内存限制: 65536kB
    描述
    你现在身处一个R*C 的迷宫中,你的位置用"S" 表示,迷宫的出口用"E" 表示。

    迷宫中有一些石头,用"#" 表示,还有一些可以随意走动的区域,用"." 表示。

    初始时间为0 时,你站在地图中标记为"S" 的位置上。你每移动一步(向上下左右方向移动)会花费一个单位时间。你必须一直保持移动,不能停留在原地不走。

    当前时间是K 的倍数时,迷宫中的石头就会消失,此时你可以走到这些位置上。在其余的时间里,你不能走到石头所在的位置。

    求你从初始位置走到迷宫出口最少需要花费多少个单位时间。

    如果无法走到出口,则输出"Oop!"。

    输入
    第一行是一个正整数 T,表示有 T 组数据。
    每组数据的第一行包含三个用空格分开的正整数,分别为 R、C、K。
    接下来的 R 行中,每行包含了 C 个字符,分别可能是 "S"、"E"、"#" 或 "."。
    其中,0 < T <= 20,0 < R, C <= 100,2 <= K <= 10。
    输出
    对于每组数据,如果能够走到迷宫的出口,则输出一个正整数,表示最少需要花费的单位时间,否则输出 "Oop!"。
    样例输入
    1
    6 6 2
    ...S..
    ...#..
    .#....
    ...#..
    ...#..
    ..#E#.
    样例输出
    7

    解题思路

    这个题目看到首先想到的是使用bfs算法,对于在给定时刻迷宫中的石头消失,使用标记要标记时间,即在某个时间某个位置,因为石头消失的时间只和 mod k有关,标记的大小设置成k就可以了。

    解题代码

    #include <cstring>
    #include <cstdio>
    #include <queue>
    
    char maze[110][110];
    int flags[110][110][15];
    int dx[4] = {0, -1, 0, 1};
    int dy[4] = {-1, 0, 1, 0};
    int R, C, K;
    
    struct state{
        int x, y;
        int time;
        state(){}
        state(int x, int y, int time){this->x = x; this->y = y; this->time = time;}
    };
    
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            scanf("%d %d %d
    ", &R, &C, &K);
            memset(maze, 0, sizeof(maze));
            memset(flags, 0, sizeof(flags));
            int x = 0, y = 0;
            for(int i = 0; i < R; i++){
                for(int j = 0; j < C; j++){
                    scanf("%c", &maze[i][j]);
                    if(maze[i][j] == 'S'){
                        x = i;
                        y = j;
                    }
                }
                getchar();
            }
            
            std::queue<state> q;
            q.push(state(x, y, 0));
            flags[x][y][0] = 1;
            
            while(!q.empty()){
                state s = q.front();
                if(maze[s.x][s.y] == 'E'){
                    printf("%d
    ", s.time);
                    break;
                }
                else{
                    for(int i = 0; i < 4; i++){
                        int x = s.x + dx[i];
                        int y = s.y + dy[i];
                        if (0 <= x && x < R && 0 <= y && y < C && (maze[x][y] != '#' || (s.time+1)%K==0)) {
                                        if (flags[x][y][(s.time + 1) % K]) continue;
                                        flags[x][y][(s.time + 1) % K] = 1;
                                        q.push(state(x, y, s.time + 1));
                                    }
                    }
                }
                q.pop();
            }
            if(q.empty()){
                printf("Oop!
    ");
            }
        }
        
        return 0;
    }
    
  • 相关阅读:
    C#中设置窗口在最前显示而其他窗口不能使用
    C#中关闭子窗口而不释放子窗口对象的方法
    C#窗体越界时鼠标还能回到初始坐标位置
    C#程序实现软件开机自动启动的两种常用方法
    C# 只开启一个程序,如果第二次打开则自动将第一个程序显示到桌面
    图标库网址收藏
    C# Winform打包部署时添加注册表信息实现开机自启动
    C# winform程序怎么打包成安装项目(VS2010图解)
    数据库的三级范式,涉及范式的问题
    基数排序
  • 原文地址:https://www.cnblogs.com/zhangyue123/p/12581848.html
Copyright © 2020-2023  润新知