• 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);
    }
  • 相关阅读:
    NumberFormat 类
    ExtJs自学教程(1):一切从API開始
    机器学习笔记——贝叶斯学习
    装饰模式
    Cocos2d-x 动手实现游戏主循环
    Solr使用入门指南
    3D数学读书笔记——矩阵进阶
    学习笔记一:关于directx sdk的安装于一些概念
    oracle-db安装
    java实现第六届蓝桥杯切开字符串
  • 原文地址:https://www.cnblogs.com/bljfy/p/8743215.html
Copyright © 2020-2023  润新知