【基础】扫雷__C++

高度提示:这里的题目解析,表示的是此人的理解和想法

题目大意:

扫雷游戏是一款十分经典的单机小游戏。在 n行 m 列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。
现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。
注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

输入描述

输入文件第一行是用一个空格隔开的两个整数n和m,分别表示雷区的行数和列数。
接下来 n行,每行m 个字符,描述了雷区中的地雷分布情况。字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。相邻字符之间无分隔符。

输出描述

输出文件包含 n 行,每行 m 个字符,描述整个雷区。用’*’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。

例如

输入:

3 3
*??
???
?*?

输出:

*10
221
1*1

题目解析

扫雷游戏理解

首先:我们先了解一下扫雷这个游戏(ps:Windows内置的小游戏中有扫雷,可以到扫雷游戏查看)

扫雷就是在规定时间内找出所有不含雷的空格

如图

那么我们来观察输入和输出的东西:

题目分析

知识点概要:

1.数组的运用:

这次我们要用到的是二维数组

前两个数字则是雷区的长和宽

用二维数组能更好的处理和输出。

首先:创建二维数组

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a,b;//分别输入的长和宽
    cin>>a>>b;
    char arr[a+2][b+2]={};
    int arr_number[a+2][b+2]={};
    for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)
            {
                cin>>arr[i][j];
                if(arr[i][j]=="*") arr_number[i][j]=10//这里的10表示雷
            }
    }
    return 0;
}

此处a,b两个数字分别是长和宽,接着再创捷两个数组

一个是char类型 一个是 int 类型

why?

那是因为 同个数组当中不会是两种或多种不同类型的数据存入,所以我们要在每个char数组的下面,弄一个int 类型的数组在进行定值,

那么为什么要在a,b后面都加2呢

那是因为我们要侦测的是一个格子周围八个格子是否有雷,当列表超出范围时,程序则会报错

所以我们需要扩大范围

则当a,b为3时,列表的情况

X X X X X
X * ? ? X
X ? ? ? X
X ? * ? X
X X X X X
(此处已赋值)

 并且赋值要从(1,1)开始 到(a,b)结束

将所有的数据都设为空 是为了防止其他不需要的空间对结果造成的干扰;

为了避免输出时int 类型char类型混一起造成程序报错 我们将“*”作为int类型数组中的10

因为一个格子周围最多也就8颗雷为什么是10

因为我喜欢

接着:我们再来实现对每个格子的遍历

for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)
        {
            if(arr_number[i][j]==10) continue;
            for(int x=i-1;x<=i+1;x++)
            {
                for(int y=j-1;y<=j+1;y++)
                {
                    if(arr_number[x][y]==10) arr_number[i][j]=arr_number[i][j]+1;
                }
            }
        }
    }

 这里有些复杂,我们拆开分析

首先:我们先分析遍历每个格子
for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)
        {
            //此处为每个格子的程序编写
            
        }
    }

通过for循环我们可以获取每个子的数据,这里就不用多说了

然后 就是每个格子的程序分析 
if(arr_number[i][j]==10) continue;
        for(int x=i-1;x<=i+1;x++)
        {
            for(int y=j-1;y<=j+1;y++)
            {
                if(arr_number[x][y]==10) arr_number[i][j]=arr_number[i][j]+1;
            }
        }

第一个if条件语句 判断是不是雷

如果是雷那么就跳过进行下一个格子的分析

如果不是则开始这个格子周围区域的分析

那么两次的for是什么意思呢?

如图

     x-1 x x+1
y-1    ???
y      ?X ?
y+1    ???

假如 说X是我们要检验的格子

要判断周围八个?的格子,我们就需要for循环对9个格子的是否有雷情况进行判断(中间为什么要判断,那是因为我懒得写中间跳过的程序)

当周围有雷时,那个空格就要加几

最后:我们要进行输出

for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)
        {
            if(arr_number[i][j]==10) cout<<"*";
            else cout<<arr_number[i][j];
        }
        cout<<endl;
    }

前两个for循环我就不多说了

看中间部分,当arr_number数组的遍历抽到10时,我们就要输出“*”

否则我们就要输出这个格子中所含有的数字。

最后的最后,我们进行代码呈现

此处实际代码与上文的代码会有所不同

#include<iostream>
using namespace std;
int main() {
	int a,b;
    cin>>a>>b;
    char arr[a+2][b+2]={};
    int arr_number[a+2][b+2]={};
    for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)
        {
            cin>>arr[i][j];
            if(arr[i][j]=='*') arr_number[i][j]=101;
        }
    }
    for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)
        {
            if(arr_number[i][j]==101) continue;
            for(int x=i-1;x<=i+1;x++)
            {
                for(int y=j-1;y<=j+1;y++)
                {
                    if(arr_number[x][y]==101) arr_number[i][j]=arr_number[i][j]+1;
                }
            }
        }
    }
    for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)
        {
            if(arr_number[i][j]==101) cout<<"*";
            else cout<<arr_number[i][j];
        }
        cout<<endl;
    }
   
     return 0;
}

实际效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老冰安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值