poj1328 贪心

题目大意: 给出n个小岛的坐标,问在海岸线上最少安装多少个雷达可以扫描到全部岛屿,每个雷达的扫描半径是d

思路:以每个岛为圆心,d为半径画圆,与海岸线交于l,r两点。每个点映射到一个区间,然后对区间按r排序,在第一个区间的r处安装雷达。判断下一个区间的做端点是否在上一个雷达的左侧,否则在该区间的右端点安装一个雷达。

 

 

#include <cmath>
#include <stdio.h>
#include <algorithm>
#include <ctime>
#include <vector>
#include <cstring>
#include <map>
using namespace std;
#define LL long long
#define ULL unsigned long long
//#define REP(i,n) for(int i=0;i<n;++i)
#define REP(i,a,b) for(int i=a;i<=b;++i)
#define INFLL (1LL)<<62
#define mset(a) memset(a,0,sizeof a)
#define FR(a) freopen(a,"r",stdin)
#define FW(a) freopen(a,"w",stdout)
#define PI 3.141592654
const LL MOD = 1000000007;
const int maxn = (int)5e4+10;
struct interval
{
	double l,r;
}I[1111];
bool cmp(interval a,interval b)
{
	return a.r<b.r;
}
int main()
{
	int n,d,x,y;
	bool flag=1;
	int ca=1;
	//FR("1.txt");
	while (scanf("%d%d",&n,&d),n||d)
	{
		flag=1;
		REP(i,0,n-1){
			scanf("%d%d",&x,&y);
			if(y>d) flag=0;
			else {
				double sq=sqrt(d*d-y*y+0.0);
				I[i].l=x-sq;
				I[i].r=x+sq;
			}
		}
		if(!flag) {printf("Case %d: -1\n",ca++);continue;}
		sort(I,I+n,cmp);
		int cnt=0;
		REP(i,0,n-1){
			cnt++;
			double temp=I[i].r;
			int k=i;
			REP(j,i+1,n-1){
				if(I[j].l>temp) 
					break;
				k=j;
			}
			i=k;
		}
		printf("Case %d: %d\n",ca++,cnt);
	}
}


你可能感兴趣的:(poj1328 贪心)