题目:
扫雷游戏是在n * n的网格上进行的。在这个网格中隐藏着m个地雷,每个地雷都位于不同的网格位置。玩家反复触碰网格位置。如果触碰到一个有地雷的位置,地雷就会爆炸,玩家就输了。如果触及不包含地雷的位置,则会出现0到8之间的整数,表示包含地雷的相邻或对角线相邻网格位置的数量。部分博弈中的一系列走法如下图所示。
这里,n是8,m是10,空白方块代表整数0,凸起的方块代表未发挥的位置,类似星号的数字代表地雷。最左边的图像代表部分游戏。从第一张图像到第二张图像,玩家已经走了两步,每次都选择了一个安全的网格位置。从第二个图像到第三个图像,玩家就没那么幸运了;他选了一个有地雷的位置,因此输了。如果玩家继续采取安全的行动,直到剩下的位置都没有了,他就赢了;这些必须遏制地雷。
你的工作是阅读部分游戏的信息,并打印相应的网格。
输入格式:
输入的第一行包含一个正整数n(n<=10)。接下来的n行表示地雷的位置。每一行用n个字符表示一行的内容: 句号表示未挖掘的位置,星号表示已挖掘的位置。接下来的n行每n个字符长: 触及的位置用x表示,未触及的位置用句点表示。示例输入对应于上面的中间图。
输出格式:
输出网格,并适当地填写每个位置。被触碰过且不包含地雷的位置应该包含0到8之间的整数。如果地雷被触碰,所有有地雷的位置都应加星号。所有其他位置都应该包含一个句号。
输入样例:
输出样例:
上思路:
这题要求我们输出一张表显示触碰到的区域(x)有没有地雷,没踩到地雷就输出0~8的数字,踩到地雷要把全屏的地雷打印出来,没触碰到的区域用(.)表示。
我先在输入的时候对地雷进行处理,只要有地雷,那该地雷周围的八个格子应该加一,如何表示出来呢?我是用数组实现的,创建一个整型二维数组,当我输入地雷时,该地雷的坐标对应的周围八个格子的坐标的值就从0变成1,那么这个时候就会出现一个问题,可能会出现arr[0][0]是地雷,那么出现arr[-1][-1],这是不对的,怎么解决这个问题呢?很简单,我从下标为1的时候开始输入,这样就避免了数组下标小于0的情况,完成上述操作后,我们就能得到一张数字表。那么接下来的工作就很简单了,上代码。
#include<stdio.h>
int main()
{
int n, i, j, arr[15][15] = {0};//arr保存绘制出来的数字图像
char ch[15][15], ch1[15][15];//ch保存地雷分布图,ch1保存触及范围图以及打印结果
scanf("%d", &n);
getchar();//至关重要,包括下面的若干个getchar(),用于吸收回车
for (i = 1; i <= n; i++) {//为什么从i=1,j=1开始?因为无需考虑越界,若从0开始,那么下面的if语句里的数组可能会越界变成-1,我这么做避免了越界
for (j = 1; j <= n; j++) {
scanf("%c",&ch[i][j]);
if (ch[i][j] == '*') {
arr[i-1][j-1]++;//从这行开始的八行,意味着地雷周围的八个点必须强制加一
arr[i-1][j+1]++;
arr[i+1][j-1]++;
arr[i+1][j+1]++;
arr[i][j-1]++;
arr[i][j+1]++;
arr[i-1][j]++;
arr[i+1][j]++;
}
}
getchar();
}
//上面嵌套for的作用就是根据输入的字符绘制数字图像arr,只要出现地雷那么就会自动扫描当前地雷的周围八个格子并加一
int flag=0;//此开关是用来控制是否恢复出厂设置,当开关为1,就说明踩到了地雷
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
scanf("%c",&ch1[i][j]);
if (ch1[i][j] == 'x' && ch[i][j] == '*') flag = 1; // 查看触及到的位置是不是地雷,是就踩到了呀
if (ch[i][j] == '*') ch1[i][j] = '*'; // 无论踩没踩到都假设踩到了地雷,后面再根据情况复原
}
getchar();
}
if (!flag) {//当开关为0,则说明没有踩到地雷,可以复原,按照原先输入的字符复原即可
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (ch1[i][j] == '*') { // 因为我们只是修改了是地雷的位置,因此只需要将*改回来就行
ch1[i][j] = '.';
}
}
}
}
for (i = 1; i <= n; i++) {//这里就是常规打印,因为在上面我们已经决定了是否打印地雷(有没有踩到地雷),所以只需判断当前的位置是不是输入的触及范围,如果是就打印对应的数字,否则输出点.
for (j = 1; j <= n; j++) {
if (ch1[i][j] == 'x') {
printf("%d", arr[i][j]);
}
else {
printf("%c", ch1[i][j]);
}
}
if(i != n) printf("\n");//注意换行
}
return 0;
}
这题的有一个测试点大家不容易发现,解决方式就是我在代码里设置的开关以及假设踩到了地雷,没踩到就复原。问题出现的原因是因为如果前面的地雷没有触及到,自然不会打印,有可能会错过打印,为什么这么说?因为有可能在之后的某行某列触及到了地雷,那么这个时候就需要打印所有地雷,但是前面的地雷已经被错过了,理应打印地雷的(*)变成了(.)那就不符合题意了.
相信大家可以看懂的,如果有不懂的可以在评论区提问哦~
——人生自古谁无死,留篇题解帮萌新——