UVa 10382 Watering Grass (贪心 区间覆盖)

利用几何关系转化以后,变成经典的区间覆盖问题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 10010;
const double eps = 1e-11;

int n, L, w;

int p[maxn], r[maxn];

struct Seg{
	double l, r;
	
	bool operator < (const Seg &x) const{
		return l < x.l || (l == x.l && r < x.r);
	}
}a[maxn];

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	while(scanf("%d%d%d", &n, &L, &w) == 3){
		double W = (double)w / 2.0;
		
		int cnt = 0;
		for(int i = 1 ; i <= n ; ++i){
			scanf("%d%d", &p[i], &r[i]);
			if(r[i] * 2 <= w) continue;
			
			double l = sqrt((double)r[i] * r[i] - W * W);
			if(p[i] - l > (double) L + eps) continue;
			
			a[++cnt].l = p[i] - l, a[cnt].r = p[i] + l;	
		}
//		for(int i = 1 ; i <= cnt ; ++i){
//			printf("%.3lf %.3lf\n", a[i].l, a[i].r);
//		}
				
		sort(a + 1, a + 1 + cnt);

		double lt = 0.0, rt = 0.0;
		int ans = 0;
		for(int i = 1 ; i <= cnt ;){
			if(a[i].l > lt + eps){
				ans = -1;
				break;
			}
			
			while(a[i].l <= lt && i <= cnt){
				rt = max(rt, a[i].r);
				++i;
			}
			
			++ans;
			lt = rt;
			if(lt - L > eps) break;
		}
		if(rt + eps < L) ans = -1;
		printf("%d\n", ans);
	}
	return 0;
}
上一篇:0.618法 && 牛顿法


下一篇:小数精度的一些问题