您的位置:首页 > 其它

poj_1328_Radar Installation(区间贪心)

2013-09-24 23:24 567 查看
題型:貪心

題意

有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 1234
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: