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; }