[贪心] UVa1615 高速公路 (区间选点问题)

题目

给定平面上n(n≤ 105 10 5 )个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的 每个点,都有一个选出的点离它的欧几里德距离不超过D。

思路

这道题的思路可是我自己一个人想出来的哦。
以每个点为圆心,以D为半径画圆,会和x轴交于两点。所以能让这个点够得到的高速公路出口,就只会在这两点之间运动了。这不就变成区间选点了吗,而且本题只让统计选点数,更简单,一个循环三行代码就能搞定。

代码

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define _for(i,a,b) for(int i = (a); i<(b); i++)
using namespace std;

const int maxn = 100000+1000;
int s,n,d;
struct qujian{
    double a,b;
    bool operator < (const struct qujian &rhs) const {
        return b<rhs.b;
    }
}A[maxn];

int main(){
    while(scanf("%d",&s) == 1){
        scanf("%d%d",&d,&n);
        int x,y; double p;
        _for(i,0,n){
            scanf("%d%d",&x,&y);
            p = sqrt(d*d-y*y);
            A[i].a = x-p;
            A[i].b = x+p;
            if (A[i].a<0) A[i].a = 0;
            if (A[i].b>s) A[i].b = s;
        }
        sort(A,A+n);
        int ans = 0;
        double last = -1;
        _for(i,0,n)  // 对于非整数的区间选点
            if(A[i].a>last) {
                last = A[i].b;
                ans++;
            }
        printf("%d\n",ans);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值