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

 

posted on 2014-05-19 21:11  天依蓝  阅读(538)  评论(0)    收藏  举报

导航