POJ1328 Radar Installation (区间选点问题,贪心)

本文详细解析了POJ 1328题目的解决思路,采用贪心算法对雷达覆盖问题进行求解。通过对坐标排序及计算各岛屿作为圆心时的覆盖范围,有效地去除了重复覆盖区域,最终确定所需的最少雷达数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址:

http://poj.org/problem?id=1328


描述:


解法:

采用贪心方法。

先排序,原先想“判断下一个坐标能否被上个坐标的圆覆盖”,coos[j].x-sqrtf(d*d-coos[j].y*coos[j].y) <= coos[i].x+sqrtf(d*d-coos[i].y*coos[i].y,后来发现这种想法是错的,比如单独来看,i的圆可以覆盖到i+1和i+2,但其实不存在i的园能同时覆盖i+1和i+2这两个坐标。给出一组数据方便理解:

4 5  //n d
-5 3
-3 5
2 3
3 3

后来采用:把每个岛屿来当做雷达的圆心,半径为d,做圆,与x轴会产生两个焦点L和R,这就是一个区间;首先就是要把所有的区间找出来,然后x轴从左往右按L排序,再然后就是所谓的贪心把那些互相重叠的区间去掉就行。

网上(http://www.tuicool.com/articles/7V3MVj)虽然通过了所有用例,但我觉得代码不对。

这个(http://blog.youkuaiyun.com/jun_sky/article/details/7000938)代码我认为是正确的。


代码:(POJ不能用lambda表达式真是wtf)

#include <iostream>
using namespace std;
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <sstream>
#define EACH(it,a) for(auto it=begin(a);it!=end(a);it++)
#define LL long long
#define INF 0x3f3f3f3f

struct scope{
	double l;
	double r;
}scopes[1000];

bool cmp(scope a,scope b)
{ 
	return (a.r<b.r);
}

int main()
{
	//ios_base::sync_with_stdio(0);
#ifdef LJY
	freopen("in.txt","r",stdin);
#endif
	int i,j,k,n,d,x,y;
	for(k=1;;k++){
		int ans=0;
		cin>>n>>d;
		if(n==0 && d==0)
			break;
		for(i=0;i<n;++i){
			cin>>x>>y;
			if(y>d || y<0)
				ans=-1;
			scopes[i].l=x-sqrtf(d*d-y*y);
			scopes[i].r=x+sqrtf(d*d-y*y);
		}
		if(ans!=-1){
			sort(scopes,scopes+n,cmp);
			i=0;
			double t=scopes[0].r;
			ans++;
			for(i=1;i<n;i++){
				if(scopes[i].l>t){
					ans++;
					t=scopes[i].r;
				}else
					t=min(scopes[i].r,t);
			}
		}

		cout<<"Case "<<k<<": "<<ans<<endl;
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值