GalaxyOJ-687 (离散化)

题目

Problem Description

DHC瘦是瘦,但有肌肉。他骨骼精奇,应堂发黑,理所当然的炼成了绝世神功“天神下凡”,DHC决定去找经常D他的KMZ报仇。KMZ拥有一片领地,几眼望不到头,所以我们认为是无限大。

DHC不敢正面和KMZ发生冲突,只敢在KMZ的领地上释放他的神功“天神下凡”,当他释放一次技能,会形成一个以目标点为圆心,半径 r 的圆形能量圈,能量圈的周围一圈有极强的能量,因此无法通过,所以圈内和圈外就被分割成了两个区域。而且能量圈也不能相交,否则会发生爆炸把DHC炸死,他当然不会犯这样的错,而内切或外切则没事。又因为DHC的神功初成,很不熟练,所以他只能以X轴上的点作为目标点。当他释放多次技能以后,地面上形成了若干个美丽的能量圈,他完全陶醉了,报仇神马的都不重要了,现在他只想知道地面被分割成了多少个区域。

Input

第一行一个正整数n,表示DHC释放了n次技能。

接下来n行,每行两个整数x,r。表示在坐标(x , 0)放了一次技能,半径为r。

1<=n<=300000,-1e9<=x<=1e9,1<=r<=1e9

Output

输出一个数,表示地面被分割成了几块。

Sample Input

4
7 5
-9 11
11 9
0 20

Sample Output

6

分析

哈哈哈,时间不多了,简单说一下,先看看程序中的注释吧

程序

#include <cstdio>
#include <algorithm>
#define L(x) l[a[x]]
#define R(x) r[a[x]]
using namespace std;
int l[300010],r[300010],a[300010],b[300010],f[300010],ans,num,n;
bool cmp(int x,int y){
    if (l[x]!=l[y]) return l[x]<l[y];
    return r[x]>r[y];
}

//处理(排过序后)第 x 个圆里面的答案,加到 ans 里,返回值为其右边出现的第一个圆
int he(int x){
    //lR记录上一个圆的右端点,F记录圆 x 是否被里面的圆分割成两半
    if (f[x]) return f[x];  //f[] 既用来判断该圆是否讨论过,也用来记录他里面总共被分成了几块,所以讨论过就直接返回了
    int ret=x+1,lR=L(x),F=1;
    for (; L(ret)<R(x) && ret<=n; ret=he(ret)){ //把 x 包着的圆都讨论一遍(这里枚举的只是里面第一层,在里面的会被继续递归)
        if (L(ret)!=lR) F=0;
        lR=R(ret);
    }
    if (lR!=R(x)) F=0;  //最后一个圆的右端点要单独判断
    if (F) ans+=2; else ans+=1;
    return f[x]=ret;
}

int main(){
    freopen("1.txt","r",stdin);
    scanf("%d",&n);
    for (int i=1,xx,rr; i<=n; i++){
        scanf("%d%d",&xx,&rr);
        l[i]=xx-rr,r[i]=xx+rr;
    }
    for (int i=1; i<=n; i++) a[i]=i;
    sort(a+1,a+n+1,cmp);    //处理好顺序,保证数组中后面的圆不会包到前面的圆,且不会在前面的圆的左边
    //还要判重,把位置大小相同的圆弄成一个
    for (int i=1; i<=n; i++) if (L(i)!=L(i-1) || R(i)!=R(i-1)) b[++num]=a[i];   
    for (int i=1,n=num; i<=n; i++) a[i]=b[i];

    for (int i=1; i<=n; i++) if (!f[i]) he(i);
    printf("%d",ans+1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值