51NOD 1278 相离的圆(二分 + 排序)

传送门

平面上有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

解题思路:

因为他们都是在 X 轴上,所以我们可以将其转为线段相交,因为要求的是圆相离的情况也就是转化后的线段不相交的情况,我们可以将线段的终点按升序排列,如果终点相等的话按起点升序,然后二分查找每一个起点,找到终点大于起点的下标,每次sum+=下标就行了。

My Code:

#include <iostream>
#include <algorithm>

using namespace std;
const int MAXN = 100000+5;
struct node
{
    int left, right, flag;
}a[MAXN];
inline bool cmp(node a, node b)
{
    if(a.right != a.right)
        return a.left < b.left;
    return a.right < b.right;
}
int Binary_search(int l, int r, int x)
{
    int mid;
    while(l < r)
    {
        mid = (l+r)>>1;
        if(a[mid].right >= x)
            r = mid-1;
        else
            l = mid+1;
    }
    while(l>0 && a[l].right>=x)
        l--;
    return l;
}

int main()
{
    int n;
    while(cin>>n)
    {
        int c, r, cnt = 0;
        for(int i=1; i<=n; i++)
        {
            cin>>c>>r;
            a[i].left = c-r;
            a[i].right = c+r;
        }
        sort(a+1, a+n+1, cmp);
        a[0].left = a[0].right = -1;
        int ans = 0;
        for(int i=1; i<=n; i++)
            ans += Binary_search(1, i, a[i].left);
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-10-26 23:34:04

51NOD 1278 相离的圆(二分 + 排序)的相关文章

51nod - 1278 相离的圆 (二分)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 因为圆心都在x轴上,把每个圆转化成线段后,按线段的起点排序,那么对于每个圆都要从后面找出起点大于当前圆转化成的线段终点的一个点,这个点之后的圆都会与当前圆相离. 因为按起点排序所以可以二分求解. 发现自己二分写的乱七八糟的. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath&

51nod 1278 相离的圆(排序+修改步长)

题目意思: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 平面上有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 <= 50

51nod 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中间用空格

1278 相离的圆(51nod)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 这道题需要用到两个姿势第一将圆相离的模型转换成线段和线段之间不想交,然后还有一个就是修改循环变量的步长.达到降低时间复杂度的效果,不过只能降低系数,并不能降低次数= = #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm>

二分排序之三行代码

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include<stdio.h>  #include<stdlib.h>  int a[]={10,22,42,51,56,63,78,99,102,118};   int binSearch(int* a, int begin, int end, int k){      int mid = begin + ( (end - begin)>>1 ),index;      index

POJ 2398 计算几何+二分+排序

Toy Storage Time Limit: 1000MS  Memory Limit: 65536K Total Submissions: 3953  Accepted: 2334 Description Mom and dad have a problem: their child, Reza, never puts his toys away when he is finished playing with them. They gave Reza a rectangular box t

二分排序法

<pre> <script type="text/javascript"> //二分排序法从小到大排序 /*算法原理: 把一组数中的N个数分为三个部分: 第1部分.中间选一个 第2部分.小于中间的一个放左边 第3部分.大于中间的一个放到右边 重复以上步骤,直到排好为止.重复次数是不确定的根据元素多少和元素顺序都有关系 假设有数组: [7,6,9,5,3]; 第一次: 取出中间一项9,如果是偶数项比如4个可以取第二个或第三个都行的. 把小于9的放到左边数组中,大于

Codeforces Round #521 (Div. 3) D. Cutting Out 【二分+排序】

任意门:http://codeforces.com/contest/1077/problem/D D. Cutting Out time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output You are given an array ss consisting of nn integers. You have to find any ar

排序算法一二分排序

二分插入排序 简介 二分排序是指利用二分法的思想对插入排序进行改进的一种插入排序算法, 可以利用数组的特点快速定位指定索引的元素. 二分法排序的思想 必须是有序数组 在插入第i个元素时,对前面的0-i-1元素进行折半,先跟他们中间的那个元素比, 如果小,则对前半再进行折半,否则对后半进行折半,直到left>right,找到位置 然后再把第i个元素前1位与目标位置之间的所有元素后移,再把第i个元素放在目标位置上. 复杂度 二分排序的时间复杂度是O(logn), 空间复杂度O(1),是稳定排序. 1