破解扫雷小游戏

扫雷矩阵的每一行每一列都是一个数字,每个数字的含义是与当前位置相邻的8个方向(上、下、左、右、左上、左下、右上、右下)中,有多少个雷(在下图中,雷用‘ * ’表示);如果当前位置就是雷的话,仍输出一个‘ * ’。

比如初始的雷矩阵如下:

. . . .

. . * *

* . * .

. * . *

对应的数字矩阵为:

0122

13**

 *4*4

2*3* 

输入:第一行两个整数n,m,代表矩阵有n行m列,接下来共n行,每行m个字符

输出:输出共n行m列,为扫雷矩阵。

输入:

4 4

....

..**

*.*.

.*.*

输出:
0122

13**

*4*4

2*3*

题目本身没有什么难于理解的地方,只需要统计一个矩阵中,每个元素周围的‘ * ’ 的个数即可。 

既然是要统计每个元素周围的‘ * ’的数量,那么就可以把数据存储到二维数组中,借助二维数组的特点进行统计并输出。

首先就是把数据存储到二维数组中,因为输入的数据全是字符,所以就要去除‘ \n ’的影响。因此要在代码中加上getchar(),保证在每次输完一行后再输入‘ \n ’时吃掉‘ \n ’,避免影响数据的输入,但若是输入时以空格隔开,则在每次输入后还要用getchar()处理空格,比较麻烦。

 当然还有另一种比较简单的方法也可以同时规避掉‘ \n ’和空格的影响,在输入数据时在‘%c’的前边加上空格就可以了。

实例如下:

正常用getchar()处理‘ \n ’: 

 在‘%c’前加上空格规避‘ \n ’和空格:

破解扫雷小游戏_第1张图片

 输入的问题解决了,就要解决统计的问题了。因为要找的是每个元素的周围八个方位,那么就要考虑到边界上的特殊情况,对于四个角只能统计三个方位,对于除四个角外的四边界只能统计五个方位,并且每种情况的条件都不一样,因此单列出来的话费时费力,还容易出错。因此在初始化数组时可以在所需要的基础上多加一圈,并且都初始化为0,在输入数据时从第二行第二列开始输入,只输入内矩阵,最外圈不管。

效果如图:

破解扫雷小游戏_第2张图片

 因为初始化时是字符数组,再以字符型式打印出来是空白的,所以打印出来的数组最外圈是一圈空白。

这样处理后再进行统计时,只统计内矩阵,就可以避免边界影响了。

 最后就是统计,可以对每个元素的八个方位进行判断后对相应元素进行赋值(最后打印是以字符型打印,所以在赋值时要加上48,赋值为字符数字),然后再打印。

代码如下:

#include 

int main() 
{
    
    int n=0;//行
    int m=0;//列
    scanf("%d %d",&n,&m);
    getchar();//吃掉最后的回车键
    char arr[1002][1002]={0};//n,m最大取1000,为避免边界影响,直接将二维数组多加一圈,且初始化为0,方便后续计算
    int i=0,j=0;
    //输入
    for(i=1;i<=n;i++)
    {
        /*
        for(j=1;j<=m;j++)
        {
            scanf("%c",&arr[i][j]);
        }
        getchar();//吃掉回车键
        */
        for(j=0;j<=m;j++)
        {
            scanf(" %c",&arr[i][j]);
            //在%c的前边加空格也可以起到吃掉回车的作用,并且如果输入的数据使用空格隔开,“ %c”还可以起到吃掉空格的作用,相对于用getchar()更加方便
        }   
    }

    //判断是否有雷
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            if(arr[i][j]=='*')
            {
                continue;//如果是雷的话就不用统计其周围雷的个数,直接跳过
            }
            else
            {
                int cun = 0;//统计雷的个数
                //因为前边定义时把数组多定义了一圈,就避免了在边界使用i-1、i+1、j-1、j+1带来的不确定性影响
				if (arr[i - 1][j] == '*') cun++;
				if (arr[i - 1][j - 1] == '*') cun++;
				if (arr[i][j - 1] == '*')cun++;
				if (arr[i + 1][j - 1] == '*') cun++;
				if (arr[i + 1][j] == '*') cun++;
				if (arr[i + 1][j + 1] == '*') cun++;
				if (arr[i][j + 1] == '*') cun++;
				if (arr[i - 1][j + 1] == '*') cun++;
				arr[i][j] = cun + 48;//转化为数字字符,因为定义的是字符型数组,应在里边储存字符,避免出问题
            }
        }
    }

    //打印
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            printf("%c",arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

也可以在打印时进行判断,先判断该元素是否为‘ * ’,是则直接打印‘ * ’,不是则用“==”对该元素八个方位分别判断后相加,打印最后相加的值(因为用“==”判断为真返回1,为假返回0)。

代码如下:

#include
int main()
{
	int n = 0, m = 0, k = 0;
	int i = 0, j = 0;
	char arr[1002][1002] = { 0 };
	scanf("%d%d", &n, &m);
    //输入
	for (i = 1; i < n+1; i++)
	{
		for (j = 1; j < m+1; j++)
			scanf(" %c", &arr[i][j]);
	}
    //打印
	for (i = 1; i < n+1; i++)
	{
		for (j = 1; j < m+1; j++)
		{
			if (arr[i][j] == '*')
				printf("*");
			else
				printf("%d", (arr[i - 1][j - 1] == '*') + (arr[i - 1][j] == '*') + (arr[i - 1][j + 1] == '*') + (arr[i][j - 1] == '*') + (arr[i][j + 1] == '*') + (arr[i + 1][j - 1] == '*') + (arr[i + 1][j] == '*') + (arr[i + 1][j + 1] == '*'));
		}//用“==”判断是否相等,相等返回“1”,否则返回“0”
		printf("\n");
	}
	return 0;
}

你可能感兴趣的:(矩阵,c语言)