样例:
4 10 0234500067 1034560500 2045600671 0000000089
答案:4
本题既可以使用深度优先搜索,也可以使用广度优先搜索
DFS代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,ans,d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//上下左右四个方向
char a[110][110];
void dfs(int x,int y){
for(int i=0;i<4;i++){
int nx=x+d[i][0];
int ny=y+d[i][1];
//判断是否符合条件:是否越界,是否已经到达过
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[nx][ny]!='0'){
a[nx][ny]='0';//标记已经到达过的点
dfs(nx,ny);
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]!='0'){
ans++;//顺藤摸瓜,a[i][j]!='0'就是藤,找到一条藤,ans++
a[i][j]='0';//标记该点
dfs(i,j);//标记藤上的所有点
}
}
}
cout<<ans<<endl;
}
BFS代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,ans,d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//上下左右四个方向
char a[110][110];
struct node{
int x,y;
};
void bfs(int x,int y){
queue<node>q;//创建队列
q.push(node{x,y});//起点入队
a[x][y]='0';//标记不能忘了
while(q.size()!=0){ //循环条件是队列非空
node ne=q.front();//保存队首点
q.pop();//出队列
for(int i=0;i<4;i++){
int nx=ne.x+d[i][0];
int ny=ne.y+d[i][1];
//判断是否符合条件:是否越界,是否已经到达过
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[nx][ny]!='0'){
a[nx][ny]='0';//标记已经到达的点
q.push(node{nx,ny});//符合条件的点入队,逐个击破
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]!='0'){
ans++;
a[i][j]='0';
bfs(i,j);
}
}
}
cout<<ans<<endl;
}
总结:
DFS(Depth First Search,深度优先搜索):根据第一个符合条件的点接着找到下一个符合条件的点,然后顺藤摸瓜,一直走到最后。
BFS(Breadth First Search,广度(宽度)优先搜索):根据第一个符合条件的点,找到下一层级所有符合条件的点,挨个分析,逐个击破。