解题思路:
分析这个问题,可以得到:整个雷区内的地雷块占少数,而安全块占多数;
通常思路为:看一块是不是地雷,不是的话,查找以它为中心矩形区域的地雷数,存入这一块;
这个方法,倒过来看,用地雷,去炸以它为中心的矩形区域内的非地雷区域,每次被炸的块加1,也就是把输出的数字,看作是被炸的次数;
得到以下总思路:
1.输入雷区的范围;
2.输入雷区存入一个二维字符数组,在输入同时,把不是雷区的字符数组赋值为' 0 ',表示未被炸;
3.循环调用函数轰炸(若此块不是地雷,没办法轰炸周围非地雷区域,返回)否则轰炸以它为中心的矩形区域内的非地雷区域,被轰炸的块加1,即表示被轰炸次数加1;
为什么说这种方法极其高效:
雷块始终是占少数,如图
* * . . .
. . . . .
. * . . .
常规思路的话,需要调用12 次函数体;
如图:
反常规思路:
#include<stdio.h> void bombing(int x,int y); int X,Y,M,N=0; int num=1; char b[100][100]; /*-------------------------------------------------------------*/ int main() { while(scanf("%d%d",&X,&Y)&&!(X==0&&Y==0)) { for(int i=0;i<X;i++) { getchar(); /*clear data buffer cache*/ for(int j=0;j<Y;j++) { scanf("%c",&b[i][j]); if(b[i][j]=='.') b[i][j]='0'; } } N++; /*the token of field;*/ for(int i=0;i<X;i++) for(int j=0;j<Y;j++) bombing(i,j); printf("Field #%d:\n",N); for(int i=0;i<X;i++) for(int j=0;j<Y;j++) {printf("%c",b[i][j]);if((j+1)%Y==0)printf("\n");} printf("\n"); } } /*-------------------------------------------------------------*/ void bombing(int x,int y) { if(b[x][y]!='*') return ; /*-------------------------------------------------------------*/ y+=1; /*up square*/ if(x>=0&&x<X&&y>=0&&y<Y&&b[x][y]!='*') { b[x][y]+=1; } /*-------------------------------------------------------------*/ y-=2; /*down square*/ if(x>=0&&x<X&&y>=0&&y<Y&&b[x][y]!='*') { b[x][y]+=1; } y+=1; /*back to start square*/ /*-------------------------------------------------------------*/ x+=1; /*right square*/ if(x>=0&&x<X&&y>=0&&y<Y&&b[x][y]!='*') { b[x][y]+=1; } /*-------------------------------------------------------------*/ x-=2; /*left square*/ if(x>=0&&x<X&&y>=0&&y<Y&&b[x][y]!='*') { b[x][y]+=1; } x+=1; /*back to start square*/ /*-------------------------------------------------------------*/ x+=1; y+=1; /*upright square*/ if(x>=0&&x<X&&y>=0&&y<Y&&b[x][y]!='*') { b[x][y]+=1; } /*-------------------------------------------------------------*/ x-=2; /*upleft square*/ if(x>=0&&x<X&&y>=0&&y<Y&&b[x][y]!='*') { b[x][y]+=1; } /*-------------------------------------------------------------*/ y-=2; /*downleft square*/ if(x>=0&&x<X&&y>=0&&y<Y&&b[x][y]!='*') { b[x][y]+=1; } /*-------------------------------------------------------------*/ x+=2; /*downright square*/ if(x>=0&&x<X&&y>=0&&y<Y&&b[x][y]!='*') { b[x][y]+=1; } /*-------------------------------------------------------------*/ /*printf("Process%d:\n",num); for(int i=0;i<X;i++) for(int j=0;j<Y;j++) {printf("%c",b[i][j]);if((j+1)%Y==0)printf("\n");} num++;*/ return ; }
然后用一个循环合并上面的轰炸过程,轰炸区域为以(x-1,y-1)为起点的3*3的矩阵;
(如果你觉得测试数据,不都是雷块占少数的话,请看题解“Minesweeper”and“Sweepmine”)
#include <stdio.h> void bombing( int x, int y ); int X, Y, M, N = 0; int num = 1; char b[100][100]; /*-------------------------------------------------------------*/ int main() { while ( scanf( "%d%d", &X, &Y ) && !(X == 0 && Y == 0) ) { for ( int i = 0; i < X; i++ ) { getchar(); /*clear data buffer cache*/ for ( int j = 0; j < Y; j++ ) { scanf( "%c", &b[i][j] ); if ( b[i][j] == '.' ) b[i][j] = '0'; } } N++; /*the token of field;*/ for ( int i = 0; i < X; i++ ) for ( int j = 0; j < Y; j++ ) if ( b[i][j] == '*' ) bombing( i - 1, j - 1 ); printf( "Field #%d:\n", N ); for ( int i = 0; i < X; i++ ) for ( int j = 0; j < Y; j++ ) { printf( "%c", b[i][j] ); if ( (j + 1) % Y == 0 ) printf( "\n" ); } printf( "\n" ); } } /*-------------------------------------------------------------*/ void bombing( int x, int y ) { for ( int i = x; i <= x + 2; i++ ) for ( int j = y; j <= y + 2; j++ ) if ( i >= 0 && i < X && j >= 0 && j < Y && b[i][j] != '*' ) b[i][j] += 1; return; }
别忘按赞哦-.-
0.0分
0 人评分
众数问题 (C语言代码)浏览:911 |
wu-淘淘的名单 (C++代码)浏览:1532 |
C语言程序设计教程(第三版)课后习题7.1 (C语言代码)浏览:642 |
printf基础练习2 (C语言代码)浏览:653 |
1025题解浏览:796 |
2006年春浙江省计算机等级考试二级C 编程题(1) (C语言代码)浏览:726 |
链表数据求和操作 (C语言代码)浏览:1035 |
C语言程序设计教程(第三版)课后习题12.2 (C语言代码)浏览:839 |
C语言程序设计教程(第三版)课后习题5.7 (C语言代码)浏览:455 |
1025题 初学者,求帮忙看下,不知道哪错了浏览:325 |