Watering Grass UVA - 10382
题意:
给出每个喷水装置的位置,和喷水半径。
给你一个长方形区域,要求你装最少的喷水装置,使得这个区域都可以被喷到水。
思路:
- 首先可以想到先把喷水装置 抽象成线段。(但是这一步要小心一下,每个喷水点在竖轴的中心)
- 之后把问题转换为了区间覆盖。
反思:
- 本题要考虑假如半径不够 w 2 \frac{w}{2} 2w的情况,那么肯定不采用这个装置。qwq。。。。
- 还要考虑,假如更新到了超过长度 l l l,那么可以不用更新了,直接break出循环。
- 一开始没考虑浮点数除法。。。(在sqrt那里。。。),后面直接全换double。
AC
#include <iostream>
#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define rep(i,y,x) for(int i=(y); i>=(x); i--)
#define mst(x,a) memset(x,a,sizeof(x))
#define pb push_back
#define sz(a) (int)a.size()
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int>pa;
typedef pair<ll,ll>pai;
const int maxn = 1e4+10;
const double eps = 1e-6;
struct QU{
double l, r;
} qu[maxn];
int main()
{
//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n;
double len, w;
while(~scanf("%d%lf%lf", &n, &len, &w)){
double p, r;
int cnt = 0;
fori(i,0,n){
scanf("%lf%lf", &p, &r);
double len = sqrt(r*r-w*w/4);///
if(r < w/2)continue;
qu[cnt++]={p-len,p+len};
}
sort(qu,qu+cnt,[&](QU x, QU y){return x.l < y.l;});
int ans = 0;
double now = 0;
for(int i=0; i<cnt; i++){
double mx = 0;
for(int j=i; j<cnt && qu[j].l <= now; j++){
//if(mx<qu[j].r)mx = qu[j].r;
mx = max(mx,qu[j].r);
i = j;
}
if(mx > now){
now = mx;
ans++;
}else break;
if(now >= len)break;///
}
if(now >= len)printf("%d\n", ans);
else printf("-1\n");
}
return 0;
}