UVA 10382 Watering Grass

https://cn.vjudge.net/problem/UVA-10382

https://uva.onlinejudge.org/external/103/10382.pdf

题目

草地上有许多喷水的水龙头,知道半径和位置,需要完全覆盖草地,选出最少的水龙头。输出最少的数量。

题解

画出三角形,变成区间覆盖问题

尽量选右端点靠右的区间(前提是包含当前的点),然后把当前点修改为右端点

如果没有包含当前点的区间则无解

右端点超过右边界就不找了……

还需要考虑能否组成三角形

priority_queue本质是堆,比较条件用来确定某元素是否向下移动,即l和r比较,如果l满足则向下移动(r向上移动)

EPS没用= =

AC代码

#include <bits/stdc++.h>
#define REP(r,x,y) for(register int r=(x); r<(y); r++)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) (void)0
#endif
#define EPS 0
using namespace std;
struct node{
	double l,r;
};
struct cmp {
	inline bool operator () (const node&l, const node&r) {
		if(fabs(l.l-r.l)>EPS) return l.l>r.l;
		return l.r<r.r;
	}
};
priority_queue<node, vector<node>, cmp> q;
int main() {
	#ifdef sahdsg
	freopen("in.txt", "r", stdin);
	#endif
	int n,l;
	double w;
	while(~scanf("%d%d%lf", &n, &l, &w)) {
		while(!q.empty())q.pop();
		w/=2;
		REP(i,0,n) {
			double p,r;
			scanf("%lf%lf", &p, &r);
			
			double ll=sqrt((double)(r*r-w*w));
			if(!isnan(ll))
			q.push((node){p-ll,p+ll});
		}
		double fi=0;
		int ans=0;
		while(!q.empty()) {
			node t=q.top(); q.pop();
			while(t.l-fi<-EPS) {
				if(t.r>=fi)
					q.push((node){fi,t.r});
				t=q.top(); q.pop();
			}
			if(t.l>fi+EPS) break;
			fi=t.r;
			ans++;
			if(fi>=l-EPS) break;
		}
		DBG("!%lf	", fi);
		if(fi<l-EPS) puts("-1");
		else printf("%d
", ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/sahdsg/p/10629064.html