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

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278

因为圆心都在x轴上,把每个圆转化成线段后,按线段的起点排序,那么对于每个圆都要从后面找出起点大于当前圆转化成的线段终点的一个点,这个点之后的圆都会与当前圆相离.

因为按起点排序所以可以二分求解.

发现自己二分写的乱七八糟的.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <vector>
 5 #include <cstring>
 6 #include <string>
 7 #include <algorithm>
 8 #include <string>
 9 #include <set>
10 #include <functional>
11 #include <numeric>
12 #include <sstream>
13 #include <stack>
14 #include <map>
15 #include <queue>
16 #pragma comment(linker, "/STACK:102400000,102400000")
17 #define CL(arr, val)    memset(arr, val, sizeof(arr))
18
19 #define ll long long
20 #define inf 0x7f7f7f7f
21 #define lc l,m,rt<<1
22 #define rc m + 1,r,rt<<1|1
23 #define pi acos(-1.0)
24
25 #define L(x)    (x) << 1
26 #define R(x)    (x) << 1 | 1
27 #define MID(l, r)   (l + r) >> 1
28 #define Min(x, y)   (x) < (y) ? (x) : (y)
29 #define Max(x, y)   (x) < (y) ? (y) : (x)
30 #define E(x)        (1 << (x))
31 #define iabs(x)     (x) < 0 ? -(x) : (x)
32 #define OUT(x)  printf("%I64d\n", x)
33 #define lowbit(x)   (x)&(-x)
34 #define Read()  freopen("a.txt", "r", stdin)
35 #define Write() freopen("b.txt", "w", stdout);
36 #define maxn 1000000000
37 #define N 2510
38 #define mod 1000000000
39 using namespace std;
40
41 struct node
42 {
43     int x,y;
44     bool operator < (const node a) const
45     {
46         if(x==a.x) return y<a.y;
47         return x<a.x;
48     }
49 }p[50001];
50 int n;
51 int erfen(int a,int b)
52 {
53     int l=a,r=n-1,mid=0;
54     while(l<=r)
55     {
56         mid=(l+r)/2;
57         if(p[mid].x>b) r=mid-1;
58         else l=mid+1;
59     }
60     if(p[mid].x<=b) mid++;
61     if(mid>=n) return n;
62     else return mid;
63 }
64
65 int main()
66 {
67     //freopen("a.txt","r",stdin);
68     int a,b;
69     scanf("%d",&n);
70     for(int i=0;i<n;i++)
71     {
72         scanf("%d%d",&a,&b);
73         p[i].x=a-b;
74         p[i].y=a+b;
75     }
76     sort(p,p+n);
77     //for(int i=0;i<n;i++)
78     //{
79       //  printf("%d %d\n",p[i].x,p[i].y);
80     //}
81     int num=0;
82     for(int i=0;i<n-1;i++)
83     {
84         int x=erfen(i+1,p[i].y);
85         num+=n-x;
86        // printf("%d %d\n",num,x);
87
88     }
89     printf("%d\n",num);
90     return 0;
91 }

当然也可以直接把p[i].x赋值给另外一个一维数组,然后就可以用upper_bound实现二分查找了.

时间: 2024-12-20 13:06:13

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

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 <=

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>

51Nod1278 相离的圆

Problem 平面上有N个圆,他们的圆心都在X轴上,给出所有圆的圆心和半径,求有多少对圆是相离的. 例如:4个圆分别位于1, 2, 3, 4的位置,半径分别为1, 1, 2, 1,那么{1, 2}, {1, 3} {2, 3} {2, 4} {3, 4}这5对都有交点,只有{1, 4}是相离的. Solution 注意圆心在坐标轴上,之前因为没看到这句话把题跳了. 然后就可以转化为线段,按照左端点排序,i代表线段循环,二分求左端点在第i条线段右端点左边的最后一个线段,他后面的线段就是相离的,加

51nod 1640 天气晴朗的魔法 二分 + 克鲁斯卡算法(kruskal算法) 做复杂了

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1640 一开始想的时候,看到要使得最大值最小,那这样肯定是二分这个最大值了,然后每一次都跑一次kruskal 这样的复杂度是O(E * 64),然后被卡TLE了 然后观察到kruskal的时候,如果最大边是val,那么比val大的是不要的了,然后整个数组也是有序的. 比如7.6.5.4.3.2.1等,这个也是可以lower_bound的,然后lower_bound后就能过

51NOD 1962 区间计数 单调栈+二分 / 线段树+扫描线

 区间计数 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 80 两个数列 {An} , {Bn} ,请求出Ans, Ans定义如下: Ans:=Σni=1Σnj=i[max{Ai,Ai+1,...,Aj}=max{Bi,Bi+1,...,Bj}] 注:[ ]内表达式为真,则为1,否则为0. 1≤N≤3.5×1051≤Ai,Bi≤N 样例解释: 7个区间分别为:(1,4),(1,5),(2,4),(2,5),(3,3),(3,5),(4,5) Input 第一行一个整数N 第二行

计算几何-圆 模板 训练指南267

#include #include #include #include #include #include #include #include #include #include #define MM(a) memset(a,0,sizeof(a)) typedef long long ll; typedef unsigned long long ULL; const double eps = 1e-10; const int inf = 0x3f3f3f3f; using namespace

hdu 3264 Open-air shopping malls 求两圆相交

对每个圆二分半径寻找可行的最小半径,然后取最小的一个半径. 对于两圆相交就只要求到两个扇形,然后减去两个全等三角形就行了. #include<cstdio> #include<iostream> #include<cmath> #include<algorithm> using namespace std; #define pi acos(-1.0) #define eps 1e-8 #define maxn 50 int n; struct point{