Left Mouse Button

FZU:http://acm.fzu.edu.cn/problem.php?pid=1920

题意:叫你玩扫雷游戏,已经告诉你地雷的位置了,问你最少点几次鼠标左键可以赢这盘扫雷

题解:直接DFS,(注意这里是8个方向搜索不是4个方向),然后把0周围的不是雷的格子置0,然后统计不是0也不是雷的格子数量,然后加上之前DFS的数量就是答案。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
char mp[12][12];
int n;
int ans,px[200],py[200];
int top,s1[200],s2[200],num;
bool visit[12][12];
void DFS(int x,int y){//dfs寻找连通0的区域有多少个
    int dir[8][2]={{1,0},{-1,0},{0,1},{0,-1},{-1,-1},{-1,1},{1,-1},{1,1}};
    for(int i=0;i<8;i++){
        int xx=x+dir[i][0];
        int yy=y+dir[i][1];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=n){
            if(mp[xx][yy]=='0'&&visit[xx][yy]==0){
                visit[xx][yy]=1;
                DFS(xx,yy);
            }
        }
    }
}
int main(){
   int test;
   scanf("%d",&test);
   int tt=1;
   while(test--){
     ans=0;
     scanf("%d",&n);
     memset(mp,-1,sizeof(mp));
     top=0;num=0;
     for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
          cin>>mp[i][j];
          if(mp[i][j]=='0'){
            px[++top]=i; py[top]=j;
            s1[++num]=i; s2[num]=j;
          }
        }
     }
      memset(visit,0,sizeof(visit));
      while(top>=1){
         int a=px[top];
         int b=py[top--];
         if(!visit[a][b]){
            visit[a][b]=1;
             ans++;
            DFS(a,b);
         }
      }
      while(num>=1){//把0周围的非雷格子至晨0
        int a=s1[num];
        int b=s2[num--];
        if(a>=2&&mp[a-1][b]!='0'&&mp[a-1][b]!='@')
            mp[a-1][b]='0';
        if(a<n&&mp[a+1][b]!='0'&&mp[a+1][b]!='@')
            mp[a+1][b]='0';
        if(b>=2&&mp[a][b-1]!='0'&&mp[a][b-1]!='@')
            mp[a][b-1]='0';
        if(b<n&&mp[a][b+1]!='0'&&mp[a][b+1]!='@')
            mp[a][b+1]='0';
        if(a>=2&&b>=2&&mp[a-1][b-1]!='0'&&mp[a-1][b-1]!='@')
            mp[a-1][b-1]='0';
        if(a>=2&&b<n&&mp[a-1][b+1]!='0'&&mp[a-1][b+1]!='@')
            mp[a-1][b+1]='0';
        if(a<n&&b>=2&&mp[a+1][b-1]!='0'&&mp[a+1][b-1]!='@')
            mp[a+1][b-1]='0';
        if(a<n&&b<n&&mp[a+1][b+1]!='0'&&mp[a+1][b+1]!='@')
            mp[a+1][b+1]='0';
      }
      for(int i=1;i<=n;i++){//统计剩余需要点击的格子
        for(int j=1;j<=n;j++){
            if(mp[i][j]!='0'&&mp[i][j]!='@')
                ans++;
        }
      }
       printf("Case %d: %d\n",tt++,ans);
   }
}
View Code

 

转载于:https://www.cnblogs.com/chujian123/p/3737696.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值