喷水装置(二)
时间限制:3000 ms | 内存限制:65535 KB
难度:4
- 描述
- 有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
- 输入
- 第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。 - 输出
- 每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。 - 样例输入
-
2 2 8 6 1 1 4 5 2 10 6 4 5 6 5
- 样例输出
-
1 2
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 10000 + 5; 8 9 struct node{ 10 double a, b; 11 }A[maxn]; 12 13 int cmp(node A, node B){ 14 return A.a < B.a; 15 } 16 17 int main(){ 18 int T; 19 scanf("%d", &T); 20 while(T--){ 21 int n, w, h, cnt = 0, x, r; 22 scanf("%d%d%d", &n, &w, &h); 23 double start = 0, h1 = h*h*1.0/4, l; 24 for(int i = 0; i < n; i++){ 25 scanf("%d%d", &x, &r); 26 if(r*r < h1){ 27 i--; n--; 28 continue; 29 } 30 l = sqrt(r*r - h1); 31 A[i].a = x-l > 0 ? x-l : 0; 32 A[i].b = x+l < w ? x+l : w; 33 } 34 sort(A, A+n, cmp); 35 int i, k = -1; 36 while(start < w && A[k+1].a <= start){ 37 double max1 = -1; 38 for(i = k+1; A[i].a <= start && i < n; i++){ 39 if(max1 < A[i].b){ 40 max1 = A[i].b; 41 k = i; 42 } 43 } 44 start = max1; 45 cnt++; 46 } 47 printf("%d\n", start < w ? 0 : cnt); 48 } 49 }
时间: 2024-08-28 10:26:46