题目描述
有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
输入
第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
输出
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。
如果不存在一种能够把整个草坪湿润的方案,请输出0。
样例输入
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5
样例输出
1
2
1 #include <stdio.h> 2 #include <math.h> 3 4 int main(int argc, const char * argv[]) { 5 int m, n; 6 int w, h; 7 float from[10001], to[10001]; 8 scanf("%d", &m); 9 while (m--) { 10 scanf("%d %d %d", &n, &w, &h); 11 int k = 1; 12 float x, r, t = h * 1.0 / 2, sq; 13 for (int i = 0; i < n; i++) { 14 scanf("%f %f", &x, &r); 15 sq = sqrt(r * r - t * t); 16 if (r > t) { 17 from[k] = x - sq; 18 to[k++] = x + sq; 19 } 20 } 21 //排序 首要关键词 from 次要关键词 to 22 for (int i = 1; i < k - 1; i++) { 23 for (int j = i + 1; j < k; j++) { 24 if (from[i] > from[j] || (from[i] == from[j] && to[i] < to[j])) { 25 float temp = from[i]; 26 from[i] = from[j]; 27 from[j] = temp; 28 temp = to[i]; 29 to[i] = to[j]; 30 to[j] = temp; 31 } 32 } 33 } 34 //判断区间头部是否覆盖 35 if (from[1] > 0) { 36 printf("0 "); 37 continue; 38 } 39 int ans = 1; 40 float flagT = to[1], flag = to[1]; 41 from[k] = w; 42 for (int i = 2; i < k; i++) { 43 if (from[i] <= flagT && to[i] > flagT && to[i] > flag) { //查找相对较大的区间 44 flag = to[i]; 45 } 46 if (from[i + 1] > flagT) { 47 flagT = flag; 48 ans++; 49 } 50 } 51 if (flagT < w) { //判断区间尾部是否覆盖 52 printf("0 "); 53 } 54 else { 55 printf("%d ", ans); 56 } 57 } 58 return 0; 59 }