这题就是一道标准的深度优先搜索题,可以用dfs递归求解。
看样例:
4 10 0234500067 1034560500 2045600671 0000000089
首先我们要定义一个用于储存输入的变量,即a[101][101]。然后n,m,表示行数和列数,再要一个ans变量计数,(一定别忘了赋初值0)。bx[101],by[101],分别表示非0数的行和列,方便输入完后寻找。
接下来就是输入了:
先输入n,m不用讲。
重点来了(敲黑板):
想直接输无空格的int型,可以用一个字符串,输入完再换回整数;
更厉害的来了:经过我的努(xia)力(gao)发现可以这样写:scanf("%1d",a[i][j]);//只输一个宽度为1的int。
核心代码:
inline void dfs(int x,int y){//参数有两个,inline是一个小优化,可以不管
a[x][y]=0;//进去一个就变0
if(a[x-1][y])//四个方向递归查找
dfs(x-1,y);
if(a[x][y+1])
dfs(x,y+1);
if(a[x+1][y])
dfs(x+1,y);
if(a[x][y-1])
dfs(x,y-1);
}
在输入中判断不为0就记录位置,用bx[]和by[]多一个就cnt++,最后只用遍历cnt-1次(多加了一个)。
代码:
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%1d",&a[i][j]);//输入
if(a[i][j]){//不是0就记录位置
bx[cnt]=i;
by[cnt]=j;
cnt++;
}
}
}
后面因为在函数dfs中和他连通的都变成了0,所以在最后只用判断哪个点有没有在之前被遍历过,没有就找那个点,且ans++。
代码:
for(int i=1;i<cnt;i++){
if(a[bx[i]][by[i]]){//如果没遍历过
dfs(bx[i],by[i]);
ans++;//进一次就++
}
}
最后附上完整AC代码:
#include<bits/stdc++.h>
using namespace std;
int a[101][101];
int bx[10001],by[10001];
inline void dfs(int x,int y){
a[x][y]=0;
if(a[x-1][y])
dfs(x-1,y);
if(a[x][y+1])
dfs(x,y+1);
if(a[x+1][y])
dfs(x+1,y);
if(a[x][y-1])
dfs(x,y-1);
}
int main(){
int n,m,ans,cnt=1;
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%1d",&a[i][j]);
if(a[i][j]){
bx[cnt]=i;
by[cnt]=j;
cnt++;
}
}
}
for(int i=1;i<cnt;i++){
if(a[bx[i]][by[i]]){
dfs(bx[i],by[i]);
ans++;
}
}
cout<<ans;
return 0;
}
(作者太懒,没写注释,相信大家看得懂!)
最后祝大家新年快乐!