贪心- poj1328 Radar Installation

针对POJ 1328题目,介绍了通过计算每个点允许的圆心范围并排序来解决半圆最少覆盖数的问题。文章详细展示了正确的贪心算法实现,并解释了为何简单的排序策略不可行。

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

题目:

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

题意:

给定若干点,以及半径长度d,问至少需要多少个这样的半圆才能把所有点覆盖掉

思路:

一开始的贪心策略是把点按照x坐标升序排序,每次把圆心定在尽可能右边的位置,然后一直wa >_<

这种策略会在

2 3

0 2

0 3

这种数据上被坑

同理对排序加上x相同时,y降序排序的优化后,会死在这种数据上

2 3

0 1

1 3


正确的贪心方法应该是把每个点允许的圆心范围算出来,对每个圆心区间进行排序贪心

代码:

	#include <stdio.h>
	#include <math.h>
	struct pos{
		double beg, end;
	};

	void sort(pos arr[],int l, int r){
		int i = l, j = r;
		pos mid = arr[(l + r) >> 1];
		while (i <= j){
			while ((arr[i].beg < mid.beg) || (arr[i].beg == mid.beg && arr[i].end<mid.end)) ++i;
			while ((arr[j].beg > mid.beg) || (arr[j].end == mid.end && arr[j].end<mid.end)) --j;
			if (i <= j){
				pos t = arr[i];
				arr[i] = arr[j];
				arr[j] = t;
				++i;
				--j;
			}
		}
		if (i < r) sort(arr, i, r);
		if (j > l) sort(arr, l, j);
		return;
	}

	int main(){
		int n, d, total = 0;
		pos arr[1005];
	
		while (scanf("%d %d", &n, &d), ++total, !(n == 0 && d == 0)){
			int ans = 1;
			for (int i = 0; i < n; ++i){
				int x, y;
				scanf("%d %d", &x, &y);
				if (y <= d){
					double t = sqrt(d*d - y*y*1.0);
					arr[i].beg = x - t;
					arr[i].end = x + t;
				}
				else ans = -1;
			}
			getchar();
			//in

			if (ans != -1){
				sort(arr, 0, n - 1);
				double radBeg = arr[0].beg, radEnd = arr[0].end;
				for (int i = 1; i < n; ++i){
					if (radEnd>=arr[i].beg){
						radBeg = arr[i].beg;
						radEnd = radEnd>arr[i].end ? arr[i].end : radEnd;
					}
					else{
						++ans;
						radBeg = arr[i].beg;
						radEnd = arr[i].end;
					}
				}
			}
			printf("Case %d: %d\n", total, ans);
		}
		return 0;
	}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值