首页 > 代码库 > Left Mouse Button

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