[Offer收割]编程练习赛11 题目3 : 岛屿3
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
H国正在进行一项持续N周的填海造岛工程。整片工程海域可以被看作是1000x1000的网格。
每周都有一块1x1的单位方格海域被填成陆地。如果我们将连成一片的陆地(一块单位方格与它上下左右4个单位方格是相连的)视为岛屿,H国想监测每周末整片海域中一共存在有多少个岛屿,以及这些岛屿的总面积和总周长各是多少。
假设工程持续三周,第一周被填的海域坐标是(0, 0),那么第一周结束后有1座岛屿、总面积是1、总周长是4:
#.. ... ...
第二周被填的海域坐标是(1, 1),那么第二周结束后有2座岛屿、总面积是2、总周长是8:
#.. .#. ...
第三周被填的海域坐标是(1, 0),那么第三周结束后有1座岛屿、总面积是3、总周长是8:
#.. ##. ...
你能完成这项任务么?
输入
第一行包含一个整数N,表示工程持续的周数。(1 <= N <= 100000)
以下N行每行包含两个整数x和y,表示当周被填的海域坐标。(0 <= x, y < 1000)
输出
输出N行,每行包含3个整数,依次是当周末岛屿的数量、总面积和总周长。
- 样例输入
-
3 0 0 1 1 1 0
- 样例输出
-
1 1 4 2 2 8 1 3 8
思路
并查集。岛屿个数为并查集集合个数a,面积为陆地方格个数b,周长为方格总周长减去重叠长度 4 * b - 2 * 重叠边数。
代码
1 import java.util.Scanner; 2 3 public class Main { 4 5 static class UF { 6 int count; 7 int[] parent; 8 9 public UF(int n) { 10 parent = new int[n]; 11 for (int i = 0; i < n; i++) { 12 parent[i] = i; 13 } 14 } 15 16 public int find(int id) { 17 while (parent[id] != id) { 18 parent[id] = parent[parent[id]]; 19 id = parent[id]; 20 } 21 return id; 22 } 23 24 public void union(int pid, int qid) { 25 int proot = find(pid); 26 int qroot = find(qid); 27 if (proot != qroot) { 28 count--; 29 parent[proot] = qroot; 30 } 31 } 32 } 33 34 private static int L = 1000; 35 36 private static int[][] dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; 37 38 private static boolean reachable(int x, int y) { 39 return x >= 0 && y >= 0 && x < L && y < L; 40 } 41 42 public static void main(String[] args) { 43 int[][] m = new int[L][L]; 44 Scanner sc = new Scanner(System.in); 45 int n = sc.nextInt(); 46 UF uf = new UF(L * L); 47 int area = 0; 48 int edges = 0; 49 while (n-- > 0) { 50 int x = sc.nextInt(); 51 int y = sc.nextInt(); 52 if (m[x][y] == 1) { 53 continue; 54 } 55 56 m[x][y] = 1; 57 uf.count++; 58 area++; 59 60 int id = x * L + y; 61 for (int[] d : dir) { 62 int nx = x + d[0]; 63 int ny = y + d[1]; 64 if (reachable(nx, ny) && m[nx][ny] == 1) { 65 edges++; 66 uf.union(id, nx * L + ny); 67 } 68 } 69 70 System.out.println(String.format("%d %d %d", uf.count, area, 4 * area - 2 * edges)); 71 } 72 } 73 }