Aizu0118 - Property Distribution - DFS求联通块(多个字符)数目 - 模板题
题意
竟然是日文题,可能我没做过Aizu这个网站的。
给出一个 n x m 的果园,其中,@ = 苹果,# = 牡蛎,* = 橙子,
求有多少个联通块。(方向:上下左右)
思路
我一开始的思路就是开三个dfs,分别处理@、#、*,
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(s[i][j]=='@')
dfs1(i,j);
else if(s[i][j]=='#')
dfs2(i,j);
else if(s[i][j]=='*')
dfs3(i,j);
}
}
但是正确的思路应该是:类似 Oil Deposits 这一题,for循环直接遍历,因为不是只有一个字符需要判断联通,是三个字符,所以传参的时候需要 dfs(x,y,s[i][j]) 传三个参数,把字符也传进去;标记遍历过的字符直接把该字符变成图中没有出现过的字符即可,少开了一个数组节省了一丢丢空间;具体看代码,还是很简单的。
AC代码
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
char s[110][110];
int n,m,to[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};
void dfs(int x,int y,char ch)
{
s[x][y]='x';
for(int i=0; i<4; i++)
{
int tx=x+to[i][0];
int ty=y+to[i][1];
// if(tx>=0&&tx<n&&ty>=0&&ty<m&&s[tx][ty]!='x')
// if(tx>=0&&tx<n&&ty>=0&&ty<m&&s[tx][ty]==s[x][y]) // 程序直接崩溃
if(tx>=0&&tx<n&&ty>=0&&ty<m&&s[tx][ty]==ch) // 因为ch不会变,是从主函数传来的,但是如果写s[x][y]的话,字符会改变
dfs(tx,ty,ch);
}
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
for(int i=0; i<n; i++)
scanf("%s",s[i]);
int ans=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(s[i][j]!='x') //相当于标记,只不过我们少开了一个book数组
{
ans++;
dfs(i,j,s[i][j]);
}
}
}
cout<<ans<<endl;
}
return 0;
}