本题考察的知识点是并查集,解决问题的关键是写出水管连通判断表,剩下来的就是对并查集操作的考察。 /* Author: ACb0y Date: 2010年11月13日15:20:47 Type:union set ProblemId: hdu 1198 Farm Irrigation Result: 3189494 2010-11-13 15:19:27 Accepted 1198 15MS 340K 3375 B G++ ACb0y */ #include <iostream> using namespace std; //上下左右 int dx[] = {0, 0, -1, 1}; int dy[] = {-1, 1, 0, 0}; int father[2550]; char g[55][55]; //水管分布图连通判断表 int check[11][4][11] = { //A上下左右 { {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, //B { {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1} }, //C { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, //D { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1} }, //E { {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, //F { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1}, {1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1} }, //G { {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1}, {1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1} }, //H { {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, //I { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1}, {1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1} }, //J { {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1} }, //K { {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1}, {0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1}, {1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1} } }; int get_father(int sun) { if (father[sun] == -1) { return sun; } else { int temp = get_father(father[sun]); father[sun] = temp; return father[sun]; } } void union_set(int a, int b) { int a_father = get_father(a); int b_father = get_father(b); if (a_father != b_father) { father[a_father] = b_father; } } int main() { int i, j, k; int m, n; #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif while (cin >> m >> n) { if (m < 0 || n < 0) { break; } memset(father, -1, sizeof(father)); for (i = 0; i < m; ++i) { for (j = 0; j < n; ++j) { cin >> g[i][j]; } } for (i = 0; i < m; ++i) { for (j = 0; j < n; ++j) { int pos = g[i][j] - 'A'; for (k = 0; k < 4; ++k) { int newx, newy; newx = j + dx[k]; newy = i + dy[k]; if (newx >= 0 && newx < n && newy >= 0 && newy < m) { int pos1 = g[newy][newx] - 'A'; if (check[pos][k][pos1]) { union_set(i * n + j, newy * n + newx); } } } } } int ans = 0; for (i = 0; i < m; ++i) { for (j = 0; j < n; ++j) { if (father[i * n + j] == -1) { ans++; } } } cout << ans << endl; } return 0; }