[POJ1328][贪心]Radar Installation

传送门
贪心

题意
n 个点的坐标( 1 n 1000 ) 然后圆的半径为 d
圆心只能在 x 轴上 然后要让最小数量的圆包围所有点
输出 n u m m i n 若不能覆盖输出-1
题解
感觉这道题还是很???..
一开始糊了个算法 感觉是对的 然后也没怎么验证算法的正确性啊?>>>
然后还有一些智障的代码错误 然后RE WA了 n n
在我 R E n n 发之后 我发现自己智障般的错误。。
之后又WA了 n n 发之后 我终于发现自己的算法错了!!...

一开始糊的是先从左到右排个序 然后尽量让点在圆的边上…..
这当然是错的咯…

其实应该先算出能覆盖该点的圆心可以在的位置的 l , r
那么我们就转换成了经典的贪心问题
最少点覆盖区间

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define db double
using namespace std;
const int N=1005;
const db eps=1e-12;
struct data{
    db x,y;
}qx[N];
struct node{
    db l,r;
}gg[N];
int vis[N];
db d;
int D,cse=0,n;

bool comp(node xx,node yy){
    return xx.r<yy.r;
}

bool check(db x){
    return x>eps;
}

int main(){
    while(scanf("%d%d",&n,&D)==2&&(n||D)){
        d=D;
        int flag=0;
        for(int i=1;i<=n;++i){
            scanf("%lf%lf",&qx[i].x,&qx[i].y);
            if(qx[i].y-d>eps) flag=1;
        }
        if(flag) {
            printf("Case %d: -1\n",++cse);
            continue;
        }
        for(int i=1;i<=n;++i){
            db temp=sqrt(d*d-qx[i].y*qx[i].y);
            gg[i].l=qx[i].x-temp;
            gg[i].r=qx[i].x+temp;
        }
        sort(gg+1,gg+1+n,comp);
        int ans=0;
        for(int i=1;i<=n;++i){
            if(!vis[i]){
                for(int j=i;j<=n;++j)
                    if(!vis[j]&&gg[j].l<=gg[i].r) vis[j]=1;
                ans++;
            }
        }
        for(int i=1;i<=n;++i) vis[i]=0;
        printf("Case %d: %d\n",++cse,ans);
    }
    return 0;
}

这么智障以后怎么成为大气呀…

这里写图片描述

猜你喜欢

转载自blog.csdn.net/LLL_Amazing/article/details/82731842