POJ_1328_Radar Installation_贪心

每次打代码打得特别惨我就想找个人类聊聊天。


题意:

x轴上方为海,其中某些整点位置存在一共n个岛屿,在x轴(海岸)上安排一些灯塔,每个灯塔的扫描半径都为d,求最少需要多少个灯塔。



Input

The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.

The input is terminated by a line containing pair of zeros

Output

For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.


一开始贪错了,按先x正向后y反向的顺序排,再找,结果WA了几遍,上厕所的时候想明白了反例。

用勾股定理可以求得每个岛在x轴上有一段范围灯塔在其中就可以扫到,因此岛的坐标其实就是这么一个区间,然后就变成了最少点覆盖区间的经典贪心问题了。


代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
#define mxn 1010
bool dcmp(double a,double b){
	return fabs(a-b)<0.0001;
}
double d;
struct point{
	double x,y;
	bool operator < (const point& in)const{
		return x+sqrt(d*d-y*y)<in.x+sqrt(d*d-in.y*in.y);
	}
	point(){}
	point(double _x,double _y){x=_x,y=_y;}
}p[mxn];
bool flag[mxn];
int n;
int main(){
	int cs=0;
	while(scanf("%d%lf",&n,&d)!=EOF){
		if(!n&&dcmp(d,0))	break;
		memset(flag,0,sizeof(flag));
		int ans=0;
		for(int i=0;i<n;++i){
			scanf("%lf%lf",&p[i].x,&p[i].y);
			if(p[i].y>d)	ans=-1;
		}
		if(ans==-1){
			printf("Case %d: -1\n",++cs);
			continue;
		}
		sort(p,p+n);
		for(int i=0;i<n;++i){
			if(flag[i])	continue;
			flag[i] = true;
			double now=p[i].x+sqrt(d*d-p[i].y*p[i].y);
			for(int j=i+1;j<n;++j){
				double cur=p[j].x-sqrt(d*d-p[j].y*p[j].y);
				if(cur<now||dcmp(cur,now)){
					flag[j]=true;
					continue;
				}
				break;
			}
			++ans;
		}
		printf("Case %d: %d\n",++cs,ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值