poj Radar Installation

题目大意:

给定x轴上方n个点的坐标和一个半径,求出x轴上的最少点的个数,使得以这些点为圆心的圆覆盖住x轴上方所有的点

解法:

首先,如果存在y>d的点,那就没有solution

由点的纵坐标和半径可以确定出覆盖住每个点的圆心的横坐标范围

将这些范围按起点优先排序,

为了尽可能的少用x轴上的点,就要使得每个点尽可能的向右

即对于范围的左端点在最左端的点,要取其右端点作为圆心位置

若紧邻的后面的范围的左端点在这个圆心的右侧,那么total++;

若后面的区间被这个区间所覆盖,那么选择后面区间的右端点(因为小区间里取了一个满足条件的点,大区间里一定可以取到)

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<string.h>
#include<cmath>
#include<algorithm>

using namespace std;
const int maxisland = 1010;
const double eps = 1e-20;
class island{
public:
	double start,end;
}Island[maxisland];

int n,d;
bool cmpIsland(const island & item1,const island &item2){ //按间隔降序排列
	double dif = fabs(item1.start - item2.start);
	if(dif < eps){  
		return item1.end < item2.end;
	}
	return item1.start < item2.start;
}
int main(){
	//freopen("2.txt","w",stdout);
	int i,j,Case = 0,xx,yy,total;
	bool toofar;
	double dis,start,end,dis1,dis2;
	while(scanf("%d%d",&n,&d)!=EOF){
		if(n == 0 && d == 0)
			break;
		memset(Island,0,sizeof(Island));
		
		toofar = false;
		for(i = 0; i < n; ++i){
			scanf("%d%d",&xx,&yy);
			if(yy > d){  //如果y方向的距离大于雷达的半径,说明不能完成
				toofar = true;
				for(j = i + 1; j < n; ++j){  //读入这一组里剩余的数据
					scanf("%d%d",&xx,&yy);
				}
				break;
			}
			dis = (double)sqrt((double)(d*d-yy * yy));
			start = (double)xx - dis;
			end = (double)xx + dis;
			Island[i].start = start; Island[i].end = end;
		}
		if(toofar){
			printf("Case %d: -1\n",++Case);
			continue;
		}
		sort(Island,Island+n,cmpIsland);
	    double left,right;
		left = Island[0].start; right = Island[0].end;
		total = 1;
		int cnt = 1;
		while(cnt < n){
		    if(Island[cnt].start > right){
				left = Island[cnt].start;
				right = Island[cnt].end;
				++total;
			}
			else if(Island[cnt].end < right){
				right = Island[cnt].end;
			}
			++cnt;
		}
		printf("Case %d: %d\n",++Case,total);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值