hunnu 11082 The Minesweeper Game(BFS)

题目来源     :        http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11082


广度搜索bfs    

最后输出的不为“#”的部分,实际上是指1、(点击处若为0)处于此处八个方向内且为0(相当于一个“感染区”)并且这个“感染区”的八个方向除了是0的情况,就必须被不为0且不为地雷的包围)。所以,从点击点开始宽度搜索它的八个方向,若其中某方向地雷数为0,则将此处的x、y压入队列,并标记此处已被访问,此处因为判断为0后,vis[x][y]会由-1更新为find(x,y),所以,当需要判断此处是否被访问过,只要查找vis[x][y]的值是否为-1即可。又由于输出中不为0且不为“#”的vis[x][y]是包围着0的(即它的八个方向中一定有0的存在,且在包围内),所以更新不为0的vis[x][y]的条件就是:have_0() 八个方向是否有0存在。

另外,需要注意的是,边界情况,所以当判断have_0()时,一定要限制x>=1&&x<=16&&y>=1&&y<=30;


代码:

#include<iostream>
#include<string.h>
using namespace std;
char map[50][50];
int vis[50][50];
int dir[8][2]={-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
typedef struct 
{
        int x,y;
}D;
D quee[10000];
int have_0(int x,int y)
{
      int flag=0;
      for(int i=0;i<8;i++)
      {
              int a=x+dir[i][0];
              int b=y+dir[i][1];
              if(vis[a][b]==0&&a>=1&&a<=16&&b>=1&&b<=30)   {flag=1;return 1;}
      }
      if(flag==0) return 0;
}
int find(int x,int y)
{
    int num=0;
    if(map[x-1][y-1]=='*') num++;
    if(map[x-1][y]=='*') num++;
    if(map[x-1][y+1]=='*') num++;
    if(map[x][y-1]=='*') num++;
    if(map[x][y+1]=='*') num++;
    if(map[x+1][y-1]=='*') num++;
    if(map[x+1][y]=='*') num++;
    if(map[x+1][y+1]=='*') num++;
    return num;
}
void bfs(int x,int y)
{         
       int front,rear;
       front=rear=0;
       quee[rear].x=x;quee[rear++].y=y;
      
       vis[x][y]=find(x,y);   
       int nx,ny;
       while(front<=rear)
       {                 
              nx=quee[front].x;
              ny=quee[front++].y;
              for(int i=0;i<8;i++)
              {
                      int a,b;
                      a=nx+dir[i][0];b= ny+dir[i][1];   
                      if(have_0(a,b)==1&&map[a][b]!='*'&&vis[a][b]==-1&&a>=1&&a<=16&&b>=1&&b<=30)   
                      {
                               vis[a][b]=find(a,b);  
                                if(find(a,b)==0)      {quee[rear].x=a;quee[rear++].y=b;}
                      }
                     
                     
              }
       }
}
int main()
{
    int t;
    int x,y;
    char str[50];
    scanf("%d",&t);
    while(t--)
    {
          scanf("%d%d",&x,&y);
          for(int i=0;i<=17;i++)
          for(int j=0;j<=31;j++)   vis[i][j]=-1;
          for(int i=1;i<=16;i++)
          {
                  scanf("%s",str);
                  for(int j=1;j<=30;j++)
                    {map[i][j]=str[j-1];  }
          }
          bfs(x,y);
          for(int i=1;i<=16;i++)
          {
                  for(int j=1;j<=30;j++)
                  {
                          if(vis[i][j]!=-1)  printf("%d",vis[i][j]);
                          else printf("#");
                   //   cout<<vis[i][j];
                  }
                 printf("\n");
          } 
          if(t!=0) printf("\n");     
    }


    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值