hiho #1310 : 岛屿 (dfs,hash)
题目2 : 岛屿
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给你一张某一海域卫星照片,你需要统计:
1. 照片中海岛的数目
2. 照片中面积不同的海岛数目
3. 照片中形状不同的海盗数目
其中海域的照片如下,"."表示海洋,"#"表示陆地。在"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。
.####.. .....#. ####.#. .....#. ..##.#.
上图所示的照片中一共有4座岛屿;其中3座面积为4,一座面积为2,所以不同面积的岛屿数目是2;有两座形状都是"####",所以形状不同的岛屿数目为3。
输入
第一行包含两个人整数:N 和 M,(1 ≤ N, M ≤ 50),表示照片的行数和列数。
以下一个 N * M 的矩阵,表示表示海域的照片。
输出
输出3个整数,依次是照片中海岛的数目、面积不同的海岛数目和形状不同的海岛数目。
- 样例输入
-
5 7 .####.. .....#. ####.#. .....#. ..##.#.
- 样例输出
-
4 2 3
思路:
深搜,搜索过的岛屿,置岛屿为x,并用一个area数组记录,搜索到的岛的面积的大小。面积不同的岛屿,通过岛屿的位置,hash出一个值,利用set的去重功能,最后判断sharp数组中有多少个元素。
注意:关于hash的时候,hash取值,我用84的时候re了,,,91AC了,猜测可能素数的效果更好一些。
AC代码:
1 #include <stdio.h> 2 #include <set> 3 using namespace std; 4 5 char s[52][52]; 6 int N, M; 7 int di[4] = {1, -1, 0, 0}; 8 int dj[4] = {0, 0, 1, -1}; 9 set<int> area, shape; 10 11 int dfs(int i, int j, int *mini, int *minj, int *maxi, int *maxj) { 12 if (i < *mini) 13 *mini = i; 14 if (i > *maxi) 15 *maxi = i; 16 if (j < *minj) 17 *minj = j; 18 if (j > *maxj) 19 *maxj = j; 20 s[i][j] = 'x'; 21 int a = 1; 22 for (int d = 0; d < 4; ++d) { 23 int ni = i + di[d], nj = j + dj[d]; 24 if (s[ni][nj] == '#') 25 a += dfs(ni, nj, mini, minj, maxi, maxj); 26 } 27 return a; 28 } 29 30 int mhash(int mini, int minj, int maxi, int maxj) { 31 int k = 79, sh = 0; 32 for (int i = mini; i <= maxi; ++i) { 33 for (int j = minj; j <= maxj; ++j) { 34 sh = sh * k + s[i][j]; 35 } 36 k*=91; 37 } 38 return sh; 39 } 40 41 int main() { 42 scanf("%d%d", &N, &M); 43 for (int i = 0; i < N; ++i) 44 scanf("%s", s[i + 1] + 1); 45 int n1 = 0; 46 for (int i = 1; i <= N; ++i) 47 for (int j = 1; j <= M; ++j) 48 if (s[i][j] == '#') { 49 n1++; 50 int mini = i, maxi = i, minj = j, maxj = j; 51 area.insert(dfs(i, j, &mini, &minj, &maxi, &maxj)); 52 shape.insert(mhash(mini, minj, maxi, maxj)); 53 } 54 printf("%d %d %d", n1, area.size(), shape.size()); 55 return 0; 56 }