您的位置:首页 > 其它

POJ 1328 Radar Installation

2015-08-19 01:34 337 查看
题目大意:

一条直线,直线上方有一些点,以直线上一些点为圆心,画半径为d的圆,求出最少要取多少个这样的圆能把所有直线上方的点全部包括在内。

解题思路:

以直线上方的那些点为圆心,以d为半径,可以画出一些与直线相交的点。

每一个这样的圆与直线交的两个点,我们把它看作是一个区间,左坐标a[i],右坐标b[i],把这个区间称为点的活动区间。

然后明显发现,要把包含其他区间的区间删掉,因为只要满足小区间则一定满足大区间。

然后以这些区间的左端点做升序排序。这时候,这些区间的右端点严格递增。

然后这道题就变成了“选出x个点,使y个区间内每个都至少有一个点。”

然后我们的直觉可以告诉我们……从前往后来看,每一个区间都应该选最后一个点。因为这样可以让更多的点满足。

关于这类“区间选点问题”,我写了一个专题,大家可以搜索一下。

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#define LL long long
#define db double
#define maxn 10000000
#define EPS 1e-15
#define max(a,b) ((a>b)?(a):(b))
#define min(a,b) ((a<b)?(a):(b))
using namespace std;

db a[1003],b[1003];
int qsort(int s,int t)
{
int i,j;
double mid,tmp;
i=s;j=t;mid=a[(i+j)/2];
while (i<=j)
{
while (a[i]<mid)    i++;
while (a[j]>mid)    j--;
if (i<=j)
{
tmp=a[i];a[i]=a[j];a[j]=tmp;
tmp=b[i];b[i]=b[j];b[j]=tmp;
i++;
j--;
}
}
if (s<j)    qsort(s,j);
if (i<t)    qsort(i,t);
}
int main(){
int n,x,y,t,d,ans;
bool flag;
db ri,xx;
scanf("%d%d",&n,&d);
t=0;
while(n!=0 || d!=0) {
flag=0; t++;
for (int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
if (y>d) flag=1;
xx=sqrt(d*d-y*y);
a[i]=x-xx; b[i]=x+xx;
}
if (flag) {
printf("Case %d: -1\n",t);
scanf("%d%d",&n,&d);
continue;
}
qsort(1,n);
ans=0;
ri=b[1]; int i=2;
while(i<=n){
if (a[i]>ri){
ans++; ri=b[i];
}
if (b[i]<ri) ri=b[i];
i++;
}
ans++;
printf("Case %d: %d\n",t,ans);
scanf("%d%d",&n,&d);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: