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