zoukankan      html  css  js  c++  java
  • [Offer收割]编程练习赛11 1487 岛屿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 
    

    面积和周长都很简单, 就是岛屿的数量比较麻烦。可以用并查集,对于n个岛屿,经过合并后剩下岛屿的数量等于n减去合并次数。
    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 1070;
    int par[1010*1010], Rank[1010*1010];
    char mp[1007][1007];
    int dir[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    int many = 0;
    
    void init()
    {
        memset(mp, '.', sizeof(mp));
        for(int i=0; i<1010*1010; ++ i)
            par[i] = i, Rank[i] = 0;
    }
    
    int Find(int x)
    {
        if(x == par[x])
            return x;
        return par[x] = Find(par[x]);
    }
    
    void unite(int x, int y)
    {
        x = Find(x), y = Find(y);
        if(Rank[x] > Rank[y])
            par[y] = x;
        else
        {
            par[x] = y;
            if(Rank[x] == Rank[y])
                Rank[y] ++;
        }
    }
    
    int solve(int x, int y)
    {
        mp[x][y] = '#';
    
        int res = 0;
        for(int i=0; i<4; ++ i)
        {
            int s = x + dir[i][0], t = y + dir[i][1];
            if(s >= 0 && t >= 0 && mp[s][t] == '#')
            {
                if(Find(s*1005+t) != Find(x*1005+y))
                {
                    many ++;
                    unite(s*1005+t, x*1005+y);
                }
                res ++;
            }
        }
        if(res == 0)
            return 4;
        if(res == 1)
            return 2;
        if(res == 2)
            return 0;
        if(res == 3)
            return -2;
        if(res == 4)
            return -4;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
    
        init();
        int n;
        cin >> n;
        int g = 0;
        for(int i=1; i<=n; ++ i)
        {
            int x, y;
            cin >> x >> y;
            g += solve(x, y);
            cout << i-many << " " << i << " " << g << endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    Response.Status http协议状态代码
    ASP.NET MVC 如何实现头压缩
    Google PR值原理和详细解说
    NodeJS 深入浅出
    C#: ToString格式
    HttpHandler实现媒体文件和图像文件的盗链(防盗链设计)
    ASP.NET MVC 使用Areas功能的常见错误
    VC中利用多线程技术实现线程之间的通信
    基于Visual C++的Winsock API研究
    键盘钩子程序
  • 原文地址:https://www.cnblogs.com/aiterator/p/6623345.html
Copyright © 2011-2022 走看看