一开始没有dfs,只是遍历一遍然后看上下左右,发现不行,还是需要dfs一下的
本质还是并查集,不过就是合并的前奏长了点
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int father[500000];
int vis[550][550];
int map[100][4];//0.1.2.3分别表示左上右下是否可连接
char s[550][550];
int n,m;
int num[550][550];
int findroot(int p){
if(father[p]!=p)
father[p]=findroot(father[p]);
return father[p];
}
void unionset(int p,int q){
father[q]=p;
}
void dfs(int i,int j){
if(i<1||i>n||j<1||j>m)return;
if(vis[i][j])return;
vis[i][j]=1;
int x=s[i][j]-'A';
int y;
int a,b;
if(i+1<=n){
y=s[i+1][j]-'A';
if(map[x][3]&&map[y][1]){
a=findroot(num[i][j]);
b=findroot(num[i+1][j]);
if(a!=b)unionset(a,b);
}
}
if(i-1>=1){
y=s[i-1][j]-'A';
if(map[x][1]&&map[y][3]){
a=findroot(num[i][j]);
b=findroot(num[i-1][j]);
if(a!=b)unionset(a,b);
}
}
if(j+1<=m){
y=s[i][j+1]-'A';
if(map[x][2]&&map[y][0]){
a=findroot(num[i][j]);
b=findroot(num[i][j+1]);
if(a!=b)unionset(a,b);
}
}
if(j-1>=1){
y=s[i][j-1]-'A';
if(map[x][0]&&map[y][2]){
a=findroot(num[i][j]);
b=findroot(num[i][j-1]);
if(a!=b)unionset(a,b);
}
}
dfs(i,j+1);
dfs(i,j-1);
dfs(i-1,j);
dfs(i+1,j);
}
int main(){
map[0][0]=map[0][1]=1;map[0][2]=map[0][3]=0;
map[1][1]=map[1][2]=1;map[1][0]=map[1][3]=0;
map[2][0]=map[2][3]=1;map[2][1]=map[2][2]=0;
map[3][2]=map[3][3]=1;map[3][0]=map[3][1]=0;
map[4][1]=map[4][3]=1;map[4][0]=map[4][2]=0;
map[5][0]=map[5][2]=1;map[5][1]=map[5][3]=0;
map[6][0]=map[6][1]=map[6][2]=1;map[6][3]=0;
map[7][0]=map[7][1]=map[7][3]=1;map[7][2]=0;
map[8][0]=map[8][2]=map[8][3]=1;map[8][1]=0;
map[9][1]=map[9][2]=map[9][3]=1;map[9][0]=0;
map[10][0]=map[10][1]=map[10][2]=map[10][3]=1;
while(scanf("%d%d",&n,&m)!=EOF){
if(m<0&&n<0)break;
int i,j;
for(i=1;i<=n;i++){
scanf("%s",s[i]+1);
}
for(i=0;i<500000;i++)father[i]=i;
int sum=1;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
num[i][j]=sum++;
}
}
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(!vis[i][j]){
dfs(i,j);
}
}
int ans=0;
for(i=1;i<sum;i++){
if(father[i]==i)ans++;
}
printf("%d\n",ans);
}
}
return 0;
}