原题链接:Minesweeper
解题思路:
使用了轰炸法,参考了 16计三梁海栩 的代码,即为发现一个雷就将周围的8个区域的值加一.
统一使用int 型的二维数组代表*和. 解决了字符型数据和数字难以保存在一起的问题
由于每个格子周围最多有8个雷,故格子里的数值不会超过8,可以用一个大于8的数来代表雷,这样就
可以在爆雷加1的时候不像char型数据那样会影响到*的保存,在遍历打印的时候只需要判断一下就
可以知道是不是雷了.
如果有兴趣的话可以指点一下我最下方注释的代码,那是我起初打出来的代码,能过测试样例,自己写的样例也能过,但是就是过不了OJ系统.
参考代码:
/* 题目描述 Minesweeper Have you ever played Minesweeper? This cute little game comes with a certain operating system whose name we can't remember. The goal of the game is to find where all the mines are located within a M x N field. The game shows a number in a square which tells you how many mines there are adjacent to that square. Each square has at most eight adjacent squares. The 4 x 4 field on the left contains two mines, each represented by a ``*'' character. If we represent the same field by the hint numbers described above, we end up with the field on the right: *... .... .*.. .... *100 2210 1*10 1110 输入 The input will consist of an arbitrary number of fields. The first line of each field contains two integers n and m ( 0 < n, m$ \le$100) which stand for the number of lines and columns of the field, respectively. Each of the next n lines contains exactly m characters, representing the field. Safe squares are denoted by ``.'' and mine squares by ``*,'' both without the quotes. The first field line where n = m = 0 represents the end of input and should not be processed. 输出 For each field, print the message Field #x: on a line alone, where x stands for the number of the field starting from 1. The next n lines should contain the field with the ``.'' characters replaced by the number of mines adjacent to that square. There must be an empty line between field outputs. 样例输入 4 4 *... .... .*.. .... 3 5 **... ..... .*... 0 0 样例输出 Field #1: *100 2210 1*10 1110 Field #2: **100 33200 1*100 */ #include <stdio.h> #include <string.h> int main (){ int n,m; int count=0; //给输出时候的filed编号用 while (1){ int i,j; int a[102][102]; //定义镶边的二维数组,包围着的边用用来防止给*周围的格子计数时候越界 for (i=0;i<102;i++){ //使用for循环给二维数组赋初始值0; for (j=0;j<102;j++){ a[i][j]=0; } } scanf("%d%d",&n,&m); //输入n*m的矩阵 getchar(); //吞掉回车 if (n==0&&m==0){ break; //当输入m=0,n=0时候结束 } count++; char str[102]; //定义一个临时的字符型数组用来给矩阵的每一行赋值 for (i=1;i<=n;i++){ scanf ("%s",&str[1]); //从键盘获得一串字符,并且自动忽略回车,从1开始为了与下面a[i][j]对应 for (j=1;j<=m;j++){ if (str[j]=='*'){ a[i][j]=99; //如果将要读入矩阵的字符是*,赋值为一个不可能的数代表为*(因为当一个空格周围最多为8个地雷,故最大为8,大于8即为不可能的数),输出的时候判断用 int k,l; //定义k,l继承i,j,避免改变i,j的值影响到后面 for (k=i-1;k<i+2;k++){ //给这个地雷的周边8个格子都加1; for (l=j-1;l<j+2;l++){ if (a[k][l]<99){ //判断一下周围8个格子是否为*,给不为*的加1 a[k][l]++; } } } } } } printf ("Field #%d:\n",count); //打印表头 for (i=1;i<=n;i++){ for (j=1;j<=m;j++){ if (a[i][j]<99){ //打印出来不为*的值 printf ("%d",a[i][j]); } else { printf("*"); //打印出来*,(大于99) } } printf ("\n"); } printf ("\n"); } return 0; } //用字符型二维数组做的,给8个边界值与中间值分别处理(过于麻烦),但是做出来的样例过了,不过过不了oj系统 //不知道为什么,自测数据也能通过,就是过不了oj /* #include <stdio.h> char a[100][100]; //定义二维数组 int change(int n,int m){ int i,j; for (i=0;i<n;i++){ for (j=0;j<m;j++){ if (a[i][j]=='*'){ //对于*的格子,给边界格子分别+1 if (i==0&&j==0){ 分别处理八个边界和一个中间的分类 if (a[i][j+1]!='*'){ a[i][j+1]+=1; } if (a[i+1][j]!='*'){ a[i+1][j]+=1; } if (a[i+1][j+1]!='*'){ a[i+1][j+1]+=1; } } if (i==0&&j<m-1&&j!=0){ if (a[i][j-1]!='*'){ a[i][j-1]+=1; } if (a[i+1][j-1]!='*'){ a[i+1][j-1]+=1; } if (a[i+1][j]!='*'){ a[i+1][j]+=1; } if (a[i+1][j+1]!='*'){ a[i+1][j+1]+=1; } if (a[i][j+1]!='*'){ a[i][j+1]+=1; } } if (i==0&&j==m-1){ if (a[i][j-1]!='*'){ a[i][j-1]+=1; } if (a[i+1][j-1]!='*'){ a[i+1][j-1]+=1; } if (a[i+1][j]!='*'){ a[i+1][j]+=1; } } if (i<n-1&&j==0&&i!=0){ if (a[i-1][j]!='*'){ a[i-1][j]+=1; } if (a[i-1][j+1]!='*'){ a[i-1][j+1]+=1; } if (a[i][j+1]!='*'){ a[i][j+1]+=1; } if (a[i+1][j+1]!='*'){ a[i+1][j+1]+=1; } if (a[i+1][j]!='*'){ a[i+1][j]+=1; } } if (i==n-1&&j==0){ if (a[i-1][j]!='*'){ a[i-1][j]+=1; } if (a[i-1][j+1]!='*'){ a[i-1][j+1]+=1; } if (a[i][j+1]!='*'){ a[i][j+1]+=1; } } if (i==n-1&&j<m-1&&j!=0){ if (a[i][j-1]!='*'){ a[i][j-1]+=1; } if (a[i-1][j-1]!='*'){ a[i-1][j-1]+=1; } if (a[i-1][j]!='*'){ a[i-1][j]+=1; } if (a[i-1][j+1]!='*'){ a[i-1][j+1]+=1; } if (a[i][j+1]!='*'){ a[i][j+1]+=1; } } if (i==n-1&&j==m-1){ if (a[i][j-1]!='*'){ a[i][j-1]+=1; } if (a[i-1][j-1]!='*'){ a[i-1][j-1]+=1; } if (a[i-1][j]!='*'){ a[i-1][j]+=1; } } if (i<n-1&&j==m-1&&i!=0){ if (a[i-1][j]!='*'){ a[i-1][j]+=1; } if (a[i-1][j-1]!='*'){ a[i-1][j-1]+=1; } if (a[i][j-1]!='*'){ a[i][j-1]+=1; } if (a[i+1][j-1]!='*'){ a[i+1][j-1]+=1; } if (a[i+1][j]!='*'){ a[i+1][j]+=1; } } if (i>0&&i<n-1&&j>0&&j<m-1) { //对于中间的采取了继承的做法,参考上面那个成功的代码 int k,l; for (k=i-1;k<i+2;k++){ for (l=j-1;l<j+2;l++){ if (a[k][l]!='*'){ a[k][l]++; } } } } } } } } int main () { int n; int m; int count; int i,j;while ( scanf( "%d %d", &n, &m ) && !(n == 0 && m == 0) ){ count++; getchar(); for (i=0;i<n;i++){ for (j=0;j<m;j++){ scanf ("%c",&a[i][j]); //读入字符并且改变字符 if (a[i][j]=='.'){ a[i][j]='0'; } } getchar(); } change(n,m); //调用处理格子的函数 printf ("Field #%d:\n",count); //打印表头 for (i=0;i<n;i++){ for (j=0;j<m;j++){ printf ("%c",a[i][j]); } printf ("\n"); } printf ("\n"); } return 0; } */
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复