zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    Palindrome Partitioning
    triangle
    Populating Next Right Pointers in Each Node(I and II)
    分苹果(网易)
    Flatten Binary Tree to Linked List
    Construct Binary Tree from Inorder and Postorder Traversal(根据中序遍历和后序遍历构建二叉树)
    iOS系统navigationBar背景色,文字颜色处理
    登录,注销
    ios 文字上下滚动效果Demo
    经常崩溃就是数组字典引起的
  • 原文地址:https://www.cnblogs.com/deadend/p/6665652.html
Copyright © 2011-2022 走看看