您的位置:首页 > 其它

POJ 1328 Radar Installation

2011-07-21 22:10 393 查看
在岸上最少安多少个雷达,可以侦测到所有的小岛
一开始思路错误,从雷达出发,使雷达的位置尽量靠右以包含更多的小岛,其实这种思想是错误的,比如有(0,2)和(1,3)两个点.雷达半径为3,按照我的思路,第一个中心点应选sqrt(32-22),这样包含第二个点还需要另一个雷达,而实际上只需要一个圆心在(1,0)的雷达就可以了.所以这种思路是错误的.
后来看了discuss,原来是以小岛为圆心去考虑,算出要侦测到这个小岛,雷达可以放的范围.然后就像活动安排问题一样,对左端点排序,去掉重复段就可以了,注意的问题见下图.



此时要选择的是ab段,而不是ac段,因为如果选择ac段的话是不能找到点同时覆盖这3个小岛的..一开始没有画图,就没有注意到这个问题,以为完全和活动安排问题一样呢..
还有就是无解的条件,不用像dicuss里说的判断那么多的,只需要判断y>d就可以了..
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct node{
double x,y;
}nod[1001];
struct side{
double l,r;
}sid[1001];
bool cmp(side a,side b){
return a.l-b.l<0;
}
int main(){
int n,d,nCase=1;
while(scanf("%d%d",&n,&d)){
if(n==0&&d==0)break;
int nosolve=0;
for(int i=0;i<n;i++){
scanf("%lf%lf",&nod[i].x,&nod[i].y);
if(nod[i].y>d)nosolve=1;//有长度大于直径时无解
}
if(nosolve==1){
printf("Case %d: -1\n",nCase++);
continue;
}
int n2=0;
for(int i=0;i<n;i++){
double x=nod[i].x,y=nod[i].y;
if(y<0)continue;//y<0的点不需要考虑
sid[n2].l=x-sqrt(d*d-y*y);
sid[n2].r=x+sqrt(d*d-y*y);
n2++;
}
sort(sid,sid+n2,cmp);//对左区间进行排序
int res=1;
double end=sid[0].r;
for(int i=1;i<n2;i++){//贪婪选择区间
if(sid[i].l>end){
res++;
end=sid[i].r;
}else if(sid[i].r<end){//避免如图所示情况
end=sid[i].r;
}
}
printf("Case %d: %d\n",nCase++,res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: