思路: 并查集
分析:
1 题目给定11快小方形,然后给定一个n*m的描述求n*m矩阵内的连通分量的个数
2 首先我们应该解决怎么保存11块小方形,我们可以利用一个思维的分量来描述,比如A我们描述成{1,0,0,1}
3 那么我们就可以做到在线进行并查集的操作,对于[i,j]这个方块,它可能和[i-1,j]和[i,j-1]进行相连,那么用i*m+j来唯一表示一个位置,那么最后枚举整个二维矩阵即可
代码:
#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 55;
const int MAXN = 10000;
int n , m;
int father[MAXN];
char mat[N][N];
int state[11][4] =
{{1,0,0,1},{1,1,0,0},{0,0,1,1},{0,1,1,0},{1,0,1,0},{0,1,0,1},
{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0},{1,1,1,1}};
void init(){
for(int i = 0 ; i < MAXN ; i++)
father[i] = i;
}
int find(int x){
if(father[x] != x)
father[x] = find(father[x]);
return father[x];
}
void Union(int x , int y){
int fx = find(x);
int fy = find(y);
father[fx] = fy;
}
void output(){
set<int> s;
for(int i = 0 ; i < n ; i++)
for(int j = 0 ; j < m ; j++)
s.insert(find(i*m+j));
printf("%d\n" , s.size());
}
int main(){
char ch;
while(scanf("%d%d%*c" , &n , &m) && n > 0){
init();
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < m ; j++){
scanf("%c" , &mat[i][j]);
ch = mat[i][j];
int x = ch-'A';
if(i && state[x][0] == 1){
int y = mat[i-1][j]-'A';
if(state[x][0] == state[y][2])
Union(i*m+j , (i-1)*m+j);
}
if(j && state[x][3] == 1){
int y = mat[i][j-1]-'A';
if(state[x][3] == state[y][1])
Union(i*m+j , i*m+j-1);
}
}
getchar();
}
output();
}
return 0;
}