2 2 DK HF 3 3 ADC FJK IHE -1 -1
23
问有多少个集合,可以深搜,也可以用并查集合并。
深搜
#include<stdio.h> #include<algorithm> #include<cstring> using namespace std; const int maxn = 55; int n, m, a[maxn][maxn][5], map[maxn][maxn], tot; int c[4] = {0,1,0,-1}; int b[4] = {-1,0,1,0}; char s[maxn]; void dfs(int x, int y, int z) { map[x][y] = z; for (int i = 1; i <= a[x][y][0]; i++) { int fx = x + b[a[x][y][i]]; int fy = y + c[a[x][y][i]]; if (!map[fx][fy]) for (int j = 1; j <= a[fx][fy][0]; j++) if (abs(a[fx][fy][j] - a[x][y][i]) == 2) dfs(fx, fy, z); } } void insert(int x, int y, char c) { switch (c - 'A'){ case 0:a[x][y][0] = 2; a[x][y][1] = 0; a[x][y][2] = 3; break; case 1:a[x][y][0] = 2; a[x][y][1] = 0; a[x][y][2] = 1; break; case 2:a[x][y][0] = 2; a[x][y][1] = 2; a[x][y][2] = 3; break; case 3:a[x][y][0] = 2; a[x][y][1] = 1; a[x][y][2] = 2; break; case 4:a[x][y][0] = 2; a[x][y][1] = 0; a[x][y][2] = 2; break; case 5:a[x][y][0] = 2; a[x][y][1] = 1; a[x][y][2] = 3; break; case 6:a[x][y][0] = 3; a[x][y][1] = 0; a[x][y][2] = 1; a[x][y][3] = 3; break; case 7:a[x][y][0] = 3; a[x][y][1] = 0; a[x][y][2] = 2; a[x][y][3] = 3; break; case 8:a[x][y][0] = 3; a[x][y][1] = 1; a[x][y][2] = 2; a[x][y][3] = 3; break; case 9:a[x][y][0] = 3; a[x][y][1] = 0; a[x][y][2] = 1; a[x][y][3] = 2; break; case 10:a[x][y][0] = 4; a[x][y][1] = 0; a[x][y][2] = 1; a[x][y][3] = 2; a[x][y][4] = 3; break; } } int main() { while (~scanf("%d%d", &n, &m), m + n != -2) { memset(a, 0, sizeof(a)); for (int i = 1; i <= n; i++) { scanf("%s", s); for (int j = 1; j <= m; j++) { insert(i, j, s[j - 1]); } } memset(map, 0, sizeof(map)); tot = 0; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) if (!map[i][j]) dfs(i, j, ++tot); printf("%d\n", tot); } return 0; }
并查集
#include<stdio.h> #include<algorithm> #include<cstring> using namespace std; const int maxn = 55; int n, m, map[maxn][maxn], tot, fa[maxn*maxn]; char s[maxn][maxn]; bool up(int x, int y) { if (s[x][y] == 'A') return true; if (s[x][y] == 'B') return true; if (s[x][y] == 'E') return true; if (s[x][y] == 'G') return true; if (s[x][y] == 'H') return true; if (s[x][y] == 'J') return true; if (s[x][y] == 'K') return true; return false; } bool down(int x, int y) { if (s[x][y] == 'C') return true; if (s[x][y] == 'D') return true; if (s[x][y] == 'E') return true; if (s[x][y] == 'H') return true; if (s[x][y] == 'I') return true; if (s[x][y] == 'J') return true; if (s[x][y] == 'K') return true; return false; } bool left(int x, int y) { if (s[x][y] == 'A') return true; if (s[x][y] == 'C') return true; if (s[x][y] == 'F') return true; if (s[x][y] == 'G') return true; if (s[x][y] == 'H') return true; if (s[x][y] == 'I') return true; if (s[x][y] == 'K') return true; return false; } bool right(int x, int y) { if (s[x][y] == 'B') return true; if (s[x][y] == 'D') return true; if (s[x][y] == 'F') return true; if (s[x][y] == 'G') return true; if (s[x][y] == 'I') return true; if (s[x][y] == 'J') return true; if (s[x][y] == 'K') return true; return false; } int find(int x) { if (fa[x] != x) fa[x] = find(fa[x]); return fa[x]; } void merge(int x, int y) { int fx = find(x); int fy = find(y); if (fx != fy) { tot++; fa[fx] = fy; } } int main() { while (~scanf("%d%d", &n, &m), m + n != -2) { for (int i = 0; i < n; i++) scanf("%s", s[i]); tot = 0; memset(map, 0, sizeof(map)); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { map[i][j] = ++tot; fa[tot] = tot; } tot = 0; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { if (up(i - 1, j - 1) && down(i - 2, j - 1)) merge(map[i][j], map[i - 1][j]); if (left(i - 1, j - 1) && right(i - 1, j - 2)) merge(map[i][j], map[i][j - 1]); } printf("%d\n", n * m - tot); } return 0; }