POJ-1328 | ZOJ-1360 Radar Installation【贪心】

题目链接:https://cn.vjudge.net/problem/ZOJ-1360

思路: 转化为区间问题,对每个岛屿,求出可以观测到它的雷达的放置区段,比如d=5,(x,y)=(0,4),则雷达可以放置在x∈[-3 ,3]这个区段上。求出所有区段后,按区段的左端点从大到小排序,若第i个区段的右端点大于第i+1个区段的左端点,那么这两个区段对应的岛屿可以用同一个雷达观测到(覆盖)。

 比如此7个区段,用3个雷达就可以全部覆盖

AC代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
struct Island {
	double x,y;   // 岛屿坐标
}Islands[maxn];
struct Block
{
	double l,r; 	 // 记录区段的左右端点的x坐标
	friend bool operator < (const Block &t1,const Block &t2) {
		return t1.l < t2.l;
	}
}Blocks[maxn];
double Maxdis(double y,double d)   // 用于计算在可以覆盖岛屿的情况下,雷达与岛屿的x方向最远距离;
{
	return sqrt(d*d - y*y);
}
int main()
{
	int n;
	double d;
	int Case = 1;
	int sum,flag;
	
	while(scanf("%d %lf",&n,&d) && n) {
		flag = 0;
		sum = 0;
		for(int i=1;i<=n;i++) {
			scanf("%lf %lf",&Islands[i].x,&Islands[i].y);
			if(abs(Islands[i].y) > d)
				flag = 1;
		}
		if(flag) {
			printf("Case %d: -1\n",Case++);
			continue;
		}
		
		//为每个岛屿找雷达放置的区段
		double dis;
		for(int i=1;i<=n;i++) {
			dis = Maxdis(Islands[i].y,d);
			Blocks[i].l = Islands[i].x - dis;
			Blocks[i].r = Islands[i].x + dis;
		}

		sort(Blocks+1,Blocks+n+1);	
		double MinR;  // 当前雷达放置所有区段的最小右端点
		for(int i=1;i<=n;)  {
			sum++;
			MinR = Blocks[i].r;
			int j;
			for(j=i+1;j<=n;j++) {
				if(Blocks[j].l <= MinR) {			
					if(Blocks[j].r < MinR)
						MinR = Blocks[j].r;
				}
				else 
					break;
			}
			i = j;
		}
		

		printf("Case %d: %d\n",Case++,sum);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42765557/article/details/84893756