• 灯塔 (数据结构)


    灯塔(LightHouse)


    Description

    As shown in the following figure, If another lighthouse is in gray area, they can beacon each other.

    For example, in following figure, (B, R) is a pair of lighthouse which can beacon each other, while (B, G), (R, G) are NOT.

    Input

    1st line: N

    2nd ~ (N + 1)th line: each line is X Y, means a lighthouse is on the point (X, Y).

    Output

    How many pairs of lighthourses can beacon each other

    ( For every lighthouses, X coordinates won't be the same , Y coordinates won't be the same )

    Example

    Input

    3
    2 2
    4 3
    5 1
    

    Output

    1
    

    Restrictions

    For 90% test cases: 1 <= n <= 3 * 105

    For 95% test cases: 1 <= n <= 106

    For all test cases: 1 <= n <= 4 * 106

    For every lighthouses, X coordinates won't be the same , Y coordinates won't be the same.

    1 <= x, y <= 10^8

    Time: 2 sec

    Memory: 256 MB

    Hints

    The range of int is usually [-231, 231 - 1], it may be too small.

    解题思路:将灯塔按照x轴由大到小排序,即将问题转化为求y的逆序对的个数。求解逆序对可以利用归并排序的思路实现。

    如下图:在某次归并的时候,左右两个数组已经排好顺序,如果遇到a[i] > a[j],则,a[j] 与a[i] 到a[n]的所有元素均构成逆序对。

    在归并排序的时候顺便统计一下逆序对的个数。

     注意,要统计的逆序对个数可能很大。

    代码如下

    #include<cstdio>
    #include<cstring>
    #define MAXN 4000005
    #define ll long long 
    using namespace std;
    
    struct node{
        ll x;
        ll y;
    } tower[MAXN];
    ll des[MAXN];
    struct node des1[MAXN];
    int N;
    ll num;
    void merg(int l, int mid, int r)
    {
        int i, j;
        int k;
        i = l;
        k = l;
        j = mid + 1;
        while(i <= mid && j <= r){
            if(tower[i].x < tower[j].x){
                des1[k].x = tower[i].x;
                des1[k++].y = tower[i++].y;
            }
            else{
                des1[k].x = tower[j].x;
                des1[k++].y = tower[j++].y;
            }
        }
        while(i <= mid){
            des1[k].x = tower[i].x;
            des1[k++].y = tower[i++].y;
        }
        while(j <= r){
            des1[k].x = tower[j].x;
            des1[k++].y = tower[j++].y;
        }
    
        for (i = l; i <= r; i++){
            tower[i].x = des1[i].x;
            tower[i].y = des1[i].y;
        }
    }
    void msort(int l, int r){
        if(l >= r - 1)
        {
            if(tower[l].x > tower[r].x){
                int x, y;
                x = tower[l].x;
                y = tower[l].y;
                tower[l].x = tower[r].x;
                tower[l].y = tower[r].y;
                tower[r].x = x;
                tower[r].y = y;
            }
            return;
        }
        int mid = (l + r) >> 1;
        msort(l, mid);
        msort(mid + 1, r);
        merg(l, mid, r);
    }
    
    void merge1(int l, int mid, int r)
    {
        int i, j;
        ll cnt = 0;
        int k = l;
        i = l;
        j = mid + 1;
        while(i <= mid && j <= r){
            if(tower[i].y < tower[j].y){
                des[k++] = tower[i++].y;
                cnt += r - j + 1;
            }
            else{
                des[k++] = tower[j++].y;
            }
        }
        while(i <= mid)
            des[k++] = tower[i++].y;
        while(j <= r)
            des[k++] = tower[j++].y;
        for (i = l; i <= r; i++){
            tower[i].y = des[i];
        }
        num += cnt;
    }
    void get_num(int l, int r)
    {
        if(l >= r - 1){
            if(tower[l].y < tower[r].y){
                num++;
            }
            else{
                int temp = tower[l].y;
                tower[l].y = tower[r].y;
                tower[r].y = temp;
            }
            return;
        }
        int mid = (l + r) >> 1;
        get_num(l, mid);
        get_num(mid + 1, r);
        merge1(l, mid, r);
    }
    
    int main()
    {
        scanf("%d", &N);
        num = 0;
        for (int i = 0; i < N; i++)
        {
            scanf("%lld %lld", &tower[i].x, &tower[i].y);
        }
        msort(0, N - 1);
        get_num(0, N - 1);
        printf("%lld
    ", num);
        
       
        return 0;
    }
    View Code
  • 相关阅读:
    编写一个脚本,用它来操纵QTP的运行
    URLbased 方式和 HTMLbased方式的差别(摘自关河)
    提供软件测试、软件开发相关服务
    数组内容的参数化问题
    IIS状态代码的含义
    不成熟的测试工具
    LR利用foxmail发邮件部分的脚本代码
    FTP的两种模式
    pop3的基本流程
    自动化测试在企业中的实施
  • 原文地址:https://www.cnblogs.com/Ido-911/p/10732504.html
Copyright © 2020-2023  润新知