51NOD 1278 相离的圆

1278 相离的圆
基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注
平面上有N个圆,他们的圆心都在X轴上,给出所有圆的圆心和半径,求有多少对圆是相离的。
例如:4个圆分别位于1, 2, 3, 4的位置,半径分别为1, 1, 2, 1,那么{1, 2}, {1, 3} {2, 3} {2, 4} {3, 4}这5对都有交点,只有{1, 4}是相离的。
Input

第1行:一个数N,表示圆的数量(1 <= N <= 50000) 第2 - N + 1行:每行2个数P,
R中间用空格分隔,P表示圆心的位置,R表示圆的半径(1 <= P, R <= 10^9)

Output

输出共有多少对相离的圆。

Input示例

4
1 1
2 1
3 2
4 1

Output示例

1

思路:
将一个线段的圆转化为长度为[P-R,P+R]的线段,将线段从小到大排序,利用线段的起点二分查找其他线段终点小于该起点的下标,相加就是总数。

#include<iostream>
#include<string.h>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 50005
#define LL long long

struct node
{
    int left,right,flag;
};
node Line[MAXN];
int N,P,R;
inline bool cmp(node a,node b)
{
    if(a.right!=b.right)
        return a.right<b.right;
    else return a.left<b.left;
}
int BinarySearch(int l,int r,int x)
{
    int mid;
    while(l<r)
    {
        mid=(l+r)>>1;
        if(Line[mid].right>=x)
            r=mid-1;
        else
            l=mid+1;
    }
    while(l>0&&Line[l].right>=x)
        l--;
    return l;
}



int main()
{
    cin>>N;
    for(int i=1;i<=N;i++)
    {
        cin>>P>>R;
        Line[i].left=P-R;
        Line[i].right=P+R;
    }
    sort(Line+1,Line+N+1,cmp);
    int ans=0;
    for(int i=1;i<=N;i++)
    {
        ans+=BinarySearch(1,i,Line[i].left);
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Fire_to_cheat_/article/details/79944512