刚学DFS,二次元发现小埋,立马开做。
原题链接:小埋与扫雷 - 洛谷
tips:解释时一些细枝末节并未在细枝末节展示,看不懂的部分直接拉到本文末尾有部分细节补充。
看题思路:
1.发现八连通,立马想起lake counting题,开始试图用dfs结题
2.通过了解3bv(扫雷专用语),思考到需要一路走到死连成一个整体算为1,确信用dfs最舒服。
题意理解:
1.3bv:最少点击数,个人理解就是空白区+没有和空白区相连的格子数,就是本题答案
解题思路(只介绍dfs如何写):
大体思路:将空白区用其他符号'.'代替,将连着空白区又连着雷的区域用其他符号'-'代替,统计剩下的0的个数和'.'形成大区域(用dfs连接)的个数
1.需要考虑这和一般区域部分题(如lake counting)不一样,不能直接将0的部分直接化为1,否则无法判断该点符不符合空白区。所以我们需要先判断能否满足空白区条件。判断条件:通过判断该点附近是否有1(也就是有雷),即可判断出是否符合空白区,具体来说,就是8格子都没有雷就代表他是个空白区。
判断具体代码:
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
nx=x+dx,ny=y+dy;
if(a[nx][ny]=='1')flag1=1;
}
}
解释:外两层循环是个简单的八方位移动的循环,nx,ny是作为假定移动后的变量,flag1用于记录符不符合空白区的变量,如果附近有雷,则为1,后面就可以直接return。
2.如果能往后运行,就代表它是空白区,以此为原点,开始寻找其他与此点连接在一起的空白区,具体就是继续用八方位探图,并利用判断语句判断是否需要深入dfs探索。
深入具体代码:
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
nx=x+dx,ny=y+dy;
if(a[nx][ny]=='0')a[nx][ny]='-';
if(nx>=0&&ny>=0&&nx<n&&ny<m&&(a[nx][ny]=='0'||a[nx][ny]=='-'))dfs(nx,ny);
}
}
解释:将数组化为'-'的解释,由于3bv的性质,它不会将既连着雷又连着空白区的'0'部分算入点击数,所以将其化为'-'避免后面统计点击数时将它统计下来,总的来说就是'-'只用于区分,不作为判断dfs进入的条件,效果暂时与'0'一致,后面也可将'-'化为'.'。至此dfs写完
3.个人通过本题对dfs的思考(可略):dfs主体使用递归,其分为两部分:(1)判断,(2)深入。本题作为dfs的一个用法,个人总结为连体效果,将部分化为整体算为1个。
全部代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN=2000;
char a[MAXN][MAXN];
int flag1,flag2;
int n,m,nx,ny,res;
void dfs(int x,int y){
flag1=0;
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
nx=x+dx,ny=y+dy;
if(a[nx][ny]=='1')flag1=1;
}
}
if(flag1==1)return ;
a[x][y]='.';
flag2=1;
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
nx=x+dx,ny=y+dy;
if(a[nx][ny]=='0')a[nx][ny]='-';
if(nx>=0&&ny>=0&&nx<n&&ny<m&&(a[nx][ny]=='0'||a[nx][ny]=='-'))dfs(nx,ny);
}
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
flag2=0;
if(a[i][j]=='0')dfs(i,j);
if(flag2==1)res++;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]=='0')res++;
}
}
cout<<res;
}
细枝末节的解释:
1.flag1作为判断是否能够进入dfs的判断条件,flag2作为是否有1个空白区的判断条件,如果flag2为真,则res增加。
2.res作为统计最少点击数的变量。