poj_1328_Radar Installation(区间贪心)

来源:互联网 发布:幸运抽奖软件 编辑:程序博客网 时间:2024/06/04 19:42

題型:貪心

題意

       有n個點在海里,現在需要用雷達將這些店覆蓋,雷達的輻射範圍是半徑為d的圓,設海岸綫為x軸,雷達要建在x軸上,問最少要多少個雷達能將這些點全部覆蓋。

分析

        既然雷達具有輻射半徑,那麽對於點(x,y),如果y>d,那麽就不可能被覆蓋到,則輸出-1;如果y<=d,那麽雷達安裝的範圍必須在[x-sqrt(d^2-y^2),x+sqrt(d^2-y^2)]區間内。

        首先求出每個點所要求的區間,然後按集合右邊界大小進行排序,然後從左邊的集合的右邊界開始找,若該邊界所處集合所屬的點沒有被覆蓋,那麽在這個集合的右邊界檢建一個雷達,然後將集合左邊界處於該雷達左邊的集合刪除,最後貪心下去即可得到答案。

代碼

#include<iostream>#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#define eps 1e-10#define maxn 1234using namespace std;struct point {    double x,y;} p[maxn];struct Node{    double l,r;    bool flag;}h[maxn];int n;double d;bool cmp(Node a,Node b) {    if(fabs(a.r - b.r) < eps)        return a.l < b.l;    return a.r < b.r;}double funl(double x,double y) {    return x - sqrt(1.0*d*d-y*y);}double funr(double x,double y) {    return x + sqrt(1.0*d*d-y*y);}int main() {    int time = 0;    while(1) {        time++;        scanf("%d%lf",&n,&d);        if(n==0 && d==0) break;        for(int i=0; i<n; i++) {            scanf("%lf%lf",&p[i].x,&p[i].y);        }        bool vis = true;        for(int i=0; i<n; i++) {            if(p[i].y > d) {                vis = false;                break;            }            h[i].l=funl(p[i].x,p[i].y);            h[i].r=funr(p[i].x,p[i].y);            h[i].flag=true;        }        if(!vis){            printf("Case %d: -1\n",time);            continue;        }        int ans=0;        sort(h,h+n,cmp);        for(int i=0;i<n;i++){            if(h[i].flag){                ans++;                for(int j=0;j<n;j++){                    if(h[j].l < h[i].r+eps && h[j].flag == true){                        h[j].flag=false;                    }                }            }        }        printf("Case %d: %d\n",time,ans);    }    return 0;}


原创粉丝点击