• 二分(老死不相往来)


    马孔多是一个奇怪的小镇,镇上的房子沿着一条河流的南岸而建,而且镇上的居民一辈子都只在自家附近一个固定半径的范围内活动,有些居民永远不会相互接触,即使他们生活一辈子也老死不相往来。 

    马孔多小镇一共有n座房子,以到镇子的西端的距离算,居民家的位置为p,他们活动的范围为r,请问马孔多小镇一共会有多少对住户之间老死不相往来。

    输入

    第1行:一个数N,表示房子的数量(1 <= N <= 50000)
    第2 - N + 1行:每行2个数P, R中间用空格分隔,P表示房子的位置,R表示这家住户的活动范围半
    径(1 <= P, R <= 10^9)

    输出

    输出共有多少对老死不相往来的住户。

    样例输入 Copy

    4
    1 1
    2 1
    3 2
    4 1

    样例输出 Copy

    1

    提示

    1. 样例解释
    4座房子分别位于1, 2, 3, 4的位置,活动范围半径分别为1, 1, 2, 1,那么{1, 2}, {1, 3} {2, 3} {2, 4} {3,4}这5对居民活动范围都有交点,只有{1, 4}是老死不相往来的。
    2. 数据范围
    对于10%的数据,1≤N≤10;
    对于40%的数据,1≤N≤2000;
    对于100%的数据,1≤N≤50000。
    题目解析:

    我们可以把每一家居民的活动范围看做圆,对于一个圆,我们可以确定它在直线上的一条直径

    [l,r],如果两个圆的直径没有交点,则可以认为这两个圆相离。


    我们用l[]r[]分别记录每个圆直径的左右端点,分别排序。从左到右遍历每个r[i],存在j使得

    l[j]>r[i]则说明j以及l值更靠右的圆都与i相离。

    排序复杂度O(nlogn);每个i比较端点使用二分复杂度为O(logn),整体O(nlogn);因此总复杂度

    O(nlogn)

    后面的二分部分还可以优化到O(n),即将所有线段的起点和终点混合排序,然后逐个访问每一个点。对于每一个起点,只要记录他前面有多少个终点即可。排序O(nlogn),遍历O(n),总的复杂度为O(nlogn)

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e7+10;
    struct node{
        int l,r;
    };
    node a[maxn];
    bool cmp(node x,node y){
        return x.l < y.l ;
    }
    int ef(int l,int r,int x){
        int ans;
        while(l<=r){
            int mid=(l+r)/2;
            if(a[mid].l<x){
                l=mid+1;
            }
            else if(a[mid].l>=x){
                r=mid-1;        
            }
        }
        return l;
    }
    int main()
    {
        int n,x,y;
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>x>>y;
            a[i].l=x-y;
            a[i].r=x+y;
        }
        sort(a,a+n,cmp);
        int ans=0;
        for(int i=0;i<n-1;i++){
            ans+=n-ef(i+1,n-1,a[i].r+1);//二分找与第i个相离的最小的那个居民 
        }                  
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    20155227 《Java程序设计》实验四 Android开发基础设计实验报告
    20155227第十二周课堂实践
    2016-2017-2 20155227实验三《敏捷开发与XP实践》实验报告
    20155227 2016-2017-2 《Java程序设计》第十周学习总结
    2016-2017-2 20155227实验二《Java面向对象程序设计》实验报告
    20155226 实验三 敏捷开发与XP实践 实验报告
    20155226 mini DC 课堂测试补交
    20155226 2016-2017-2 《Java程序设计》第10周学习总结
    2015526 《Java程序设计》实验二实验报告
    20155226 2016-2017-2 《Java程序设计》第9周学习总结
  • 原文地址:https://www.cnblogs.com/lipu123/p/12170160.html
Copyright © 2020-2023  润新知