紫书 习题8-11 UVa 1615 (区间选点问题)

这个点就是贪心策略中的区间选点问题。

把右端点从大到小排序, 左端点从小到大排序。

每次取区间右端点就可以了, 到不能覆盖的时候就ans++, 重新取点

ps:这道题不考虑精度也可以过

        要着重复习一下区间相关问题了, 包括前面没有例题的知识点的部分

#include<cstdio> 
#include<cmath>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;

const int MAXN = 112345;
struct node
{
	double l, r;
	node(double l = 0, double r = 0) : l(l), r(r) {}
}a[MAXN];
double L, dis;
int n;

void add(int i, double x, double y)
{
	double t = sqrt(dis * dis - y * y); 
	double l = x - t, r = x + t;
	a[i] = node(l, r);
}

bool cmp(node a, node b)
{
	if(a.r != b.r)
		return a.r < b.r;
	return a.l > b.l;
}

int main()
{
	while(~scanf("%lf%lf%d", &L, &dis, &n))
	{
		REP(i, 0, n) 
		{
			double x, y;
			scanf("%lf%lf", &x, &y);
			add(i, x, y);
		}
		
		sort(a, a + n, cmp);
		int ans = 1;
		double ma = a[0].r;
		
		REP(i, 1, n)
			if(a[i].l > ma)
			{
				ans++;
				ma = a[i].r;
			}

		printf("%d\n", ans);
	}

	return 0;
}

posted @ 2018-05-06 17:48  Sugewud  阅读(104)  评论(0编辑  收藏  举报