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\t", fi);
if(fi<l-EPS) puts("-1");
else printf("%d\n", ans);
}
return 0;
}