zoukankan      html  css  js  c++  java
  • 18清明校内测试T3

    扫雷(mine)

    Time Limit:1000ms   Memory Limit:128MB

     

    题目描述

    rsy最近沉迷于一款叫扫雷的游戏。

    这个游戏是这样的。一开始网格上有n*m个位置,其中有一些位置有雷。每次rsy可以左键点击一个方块,此时若这个方块是雷,则rsy被炸,游戏结束,否则如果这个位置周围8格有x个雷,则会显示数字x。特别地,当x=0时,系统会自动左键点击附近8个位置。(此时附近8个位置一定没有雷,假如附近8个位置仍存在x=0,则继续往外扩展)想要更进一步获得关于题目的信息,打开程序->附近->游戏->扫雷或者直接打开下发的可执行文件。

    或者rsy右键点击一个位置,标注这个位置是雷。

    不幸的是,她鼠标不能左右键同时点击,因此只需考虑她左键点击与右键点击就可以了。

    注意游戏胜利的条件是所有非雷的位置都被左键点击到。(特别地,当一开始时n*m个位置都是雷时,LYK自动获得胜利)

    rsy从网上下载了金手指,很轻易地就掌握了所有雷所在的位置。rsy想通过最少的点击次数获得胜利(这里的点击次数不包括系统自动点击)。于是他来请求你的帮助。

     

    输入格式(mine.in)

        第一行两个数n,m。

        接下来n行,每行m个数ai,j,表示这个矩阵。若ai,j=’*’则表示这个位置是雷,若ai,j=’.’则表示不是雷。

     

    输出格式(mine.out)

    一个数表示答案。

     

    输入样例

    3 3

    ..*

    ...

    ..*

     

    输出样例

    2

     

    对于30%的数据n=1;

    对于另外20%的数据n,m<=3;

    对于再另外20%的数据*大致占矩阵的2/3且数据随机。

    对于100%的数据n,m<=1000。

     

     

    Hint:

    适度游戏益脑,沉迷游戏伤身。


    因为数据范围并不是很大,所以带优化的搜索应该能过。

    于是乎开始敲代码。

    但是写着写着发现一个问题,如果一个非雷的点的八个方向上有雷,但是通过鼠标右键将它标记之后,如果在点这个非雷的点,是否会出现系统自动点击周围的点。我在这里纠结了很长时间,到最后让老师用std跑了一组数据就知道根本不用考虑这么多。

    就是下面这组

    3 3
    ...
    ..*
    ...
    

    至于为什么自己想吧。

    下面来看看正解。没错就是搜索。


     

    我们来设计一下BFS做这道题,首先应该把每个点周围的雷的数量存在一个数组中去,然后每一个点都判断一下,如果这个点周围没有雷,并且这里不是雷而且没有被访问过,那就可以就从这里向外扩展,不过要记得在BFS之前就将要进行扩展的点标记为访问。就可以了。

    扩展的时候把这个这个点周围的点全部标记,如果被标记的点内存在周围没有雷的点,就把这个点扔到队列里去。继续扩展

    整张地图全扩展完了之后,还要判断一下有没有落单的点,有的话,就ans++

    代码

    #include <iostream>
    #include <cstdio>
    #include <queue>
    
    using namespace std;
    
    int n, m, ans;
    char map[1005][1005];
    int dx[10] = {1, -1, 0, 0, 1, -1, 1, -1};
    int dy[10] = {0, 0, 1, -1, -1, 1, 1, -1};
    struct node {
        int x, y;
    };
    bool vis[1005][1050];
    int num[1005][1005];
    queue<node> P;
    
    void bfs(node now) {
        while(!P.empty()) {
            now = P.front();
            P.pop();
            int x = now.x, y = now.y;
            for(int k=0; k<8; k++) {
                int xx = dx[k]+x, yy = dy[k]+y;
                if(xx <= n&&xx > 0&&yy <= m&&yy > 0&&map[xx][yy] == '.'&&vis[xx][yy] == 0) {
                    vis[xx][yy] = 1;
                    if(num[xx][yy] == 0) {
                        P.push((node) {xx, yy});
                    }
                }
            }
        }
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i=1; i<=n; i++) {
            scanf("%s", map[i]+1);
        }
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++) {
                if(map[i][j] == '.') {
                    for(int k=0; k<8; k++) {
                        if(map[i+dx[k]][j+dy[k]] == '*') {
                            num[i][j]++;
                        }
                    }
                }
                else {
                    num[i][j] = 1;
                }
            }
        }
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++) {
                if(vis[i][j] == 0&&num[i][j] == 0) {
                    P.push((node) {i, j});
                    vis[i][j] = 1;
                    bfs(P.front());
                    ans++;
                }
            }
        }
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=m; j++) {
                if(vis[i][j] == 0&&map[i][j] != '*')
                    ans++;
            }
        }
        printf("%d", ans);
    }
  • 相关阅读:
    java OA系统 自定义表单 流程审批 电子印章 手写文字识别 电子签名 即时通讯
    flowable 获取当前任务流程图片的输入流
    最新 接口api插件 Swagger3 更新配置详解
    springboot 集成 activiti 流程引擎
    java 在线考试系统源码 springboot 在线教育 视频直播功能 支持手机端
    阿里 Nacos 注册中心 配置启动说明
    springboot 集成外部tomcat war包部署方式
    java 监听 redis 过期事件
    springcloudalibaba 组件版本关系
    java WebSocket 即时通讯配置使用说明
  • 原文地址:https://www.cnblogs.com/bljfy/p/8743215.html
Copyright © 2011-2022 走看看