解题思路:
分析这个问题,可以得到:整个雷区内的地雷块占少数,而安全块占多数;


通常思路为:看一块是不是地雷,不是的话,查找以它为中心矩形区域的地雷数,存入这一块;


这个方法,倒过来看,用地雷,去炸以它为中心的矩形区域内的非地雷区域,每次被炸的块加1,也就是把输出的数字,看作是被炸的次数;

得到以下总思路:

1.输入雷区的范围;

2.输入雷区存入一个二维字符数组,在输入同时,把不是雷区的字符数组赋值为' 0 ',表示未被炸;

3.循环调用函数轰炸(若此块不是地雷,没办法轰炸周围非地雷区域,返回)否则轰炸以它为中心的矩形区域内的非地雷区域,被轰炸的块加1,即表示被轰炸次数加1;


为什么说这种方法极其高效:

雷块始终是占少数,如图

*  * .  .  . 

.  .  .  .  .

.  .  .

常规思路的话,需要调用12 次函数体;

如图:



反常规思路:

2017-12-15 22-23-57屏幕截图.png



#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;
}


别忘按赞哦-.-


点赞(21)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论