UVA - 1615 Highway(贪心-区间选点问题)

题目:

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

思路:

先自己造区间,然后贪心选点就可以了。之前做过一到类似的题目还是没有一眼看出来。

区间的造法,就是以给出的点为圆心,以D为半径画圆,这个圆与x轴的相交的两个点就是我们造的区间的左右两个端点。

然后以右端点从小到大排序贪心。(自己举了一个例子发现左端点要比右端点多)

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e3
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int maxn = 100010;
double L,D;
int n;
struct Region{
    double l, r;
}reg[maxn];

double dist(double y){
    return sqrt(D*D-y*y);
}

bool cmd(Region a,Region b){
    return a.r<b.r;
}

int main(){
    //FRE();
    while(scanf("%lf",&L)!=EOF){
        scanf("%lf",&D);
        scanf("%d",&n);
        for(int i=0; i<n; i++){
            double x,y;
            scanf("%lf%lf",&x,&y);
            reg[i].l = max(x-dist(y),0.0);
            reg[i].r = min(x+dist(y),L);
        }
        sort(reg,reg+n,cmd);

        int ans = 0,pos = -1;
        for(int i=0; i<n; i++){
            if(pos<reg[i].l||pos>reg[i].r){
                ans++;
                pos = reg[i].r;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sykline/p/10348200.html