题意:有一块草坪,长为l,宽为w,再起中心线的不同位置处装有n个点状的喷水装置。每个喷水装置i可以将以它为中心,半径为ri的圆形区域润湿,请选择尽量少的喷水装置,把整个草坪全部润湿。
分析:对于直径小于宽度的喷水装置其实可以忽略,剩下的问题转换成了最小区间覆盖问题,即:用最少数量的区间去覆盖给定的区间
1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <math.h> 5 #define zz 6 using namespace std; 7 const int MAXN = 11111; 8 pair<double, double>a[MAXN]; 9 int main(){ 10 #ifndef zz 11 freopen("in.txt", "r", stdin); 12 #endif 13 int n; 14 double l, w; 15 while(scanf("%d%lf%lf", &n, &l, &w)!=EOF){ 16 int i, j, m = 0; 17 for(i=0; i<n; i++){ 18 double p, r; 19 scanf("%lf%lf", &p, &r); 20 if(2*r<=w) continue; 21 double tmp = sqrt(r*r-w*w/4); 22 a[m++] = make_pair(p-tmp, p+tmp); 23 } 24 sort(a, a+m); 25 int cnt = 0; 26 bool flag = false; 27 double low = 0, up = 0; 28 for(i=0; i<m; i++){ 29 if(a[i].first>up) break; 30 if(a[i].second>up){ 31 for(j=i; j<m&&a[j].first<=low; j++) 32 if(up<a[j].second) up = a[j].second; 33 cnt++; 34 if(up>=l) {flag = true; break;} 35 low = up; 36 } 37 } 38 if(flag) printf("%d\n", cnt); 39 else puts("-1"); 40 } 41 }
时间: 2024-10-08 17:56:13