题目链接:https://www.luogu.com.cn/problem/P1451
题目图片:
题目理解:xzh的巧妙理解方法
题目思路使用dfs:开始对矩阵进行搜索,搜索到一个不为0的数就s++,开始dfs。
dfs的作用:寻找一片细胞,防止重复,从第一个发现的开始,一直搜索下去,只要有路径可以到达的,如果不为0就设为0,防止重复。
代码如下:
#include <iostream> using namespace std; const int w[105][105]={{0,0},{0,1},{0,-1},{1,0},{-1,0}};//上下左右四个方向 char a[105][105]; int n,m; int dfs(int x,int y){ int xx,yy; for(int i=1;i<=4;i++){ xx=x+w[i][0]; //移动 yy=y+w[i][1]; a[x][y]='0'; //已经搜索到了,设为0 if(xx>n||xx<1||yy<1||yy>m||a[xx][yy]=='0'){ //判断边界 continue; } a[xx][yy]='0'; //设为0 dfs(xx,yy); //继续搜索 } return 0; } int main() { cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>a[i][j]; } } int s=0; for(int i=1;i<=n;i++){ //开始寻找 for(int j=1;j<=m;j++){ if(a[i][j]!='0'){ s++; dfs(i,j); //只要是同一个细胞就为0 } } } cout<<s; return 0; }
心得:1)理解题意,此题理解不便,可像xzh一样改变字母便于理解
2)利用dfs一路走到黑,知道碰到边界或者'0'才停止。
可以想象为第一个不为0的数字变为0之后有了扩散作用,向四周进行扩散,知道碰到'0'或者边界才停止扩散。
3)一种新鲜的输入方法,就是输整数可以连续输一个整数(不用打空格)。
所以可以用以下方式读入整个矩阵
4)上下左右移动巧妙地利用数组的四组元素,这是通法,向上下左右移动!!!
```cpp for(c=1;c<=m;c++)//循环变量稍微有点奇怪 { for(d=1;d<=n;d++) { scanf("%1d",&mapp[c][d]); } }
类比于用scanf读入整数的时候可以控制读入的位数,比如 scanf("%2d",&m);