nyoj 题目6 喷水装置

喷水装置(一)

时间限制:3000 ms  |  内存限制:65535 KB
难度:3
 
描述
现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。
 
输入
第一行m表示有m组测试数据
每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,随后的一行,有n个实数ri,ri表示该喷水装置能覆盖的圆的半径。
输出
输出所用装置的个数
样例输入
2
5
2 3.2 4 4.5 6 
10
1 2 3 1 2 1.2 3 1.1 1 2
样例输出
2
5

这个题涉及到贪心法和数学知识
如图

对于一个半径 比1大的圆,其有效覆盖长度为橙色部分,即sqrt(r*r-1*1)*2

而对于半径小于等于1的圆,无有效覆盖长度。

因为题目保证可以覆盖,那么在排序后,涉及到小于1的半径之前,一定可以覆盖完。

代码如下

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 double r[602];
 7 
 8 bool cmp(double a, double b) {
 9     return a > b;
10 }
11 
12 int main(int argc, char const *argv[])
13 {
14     int n;
15     while(scanf("%d",&n) != EOF) {
16         double t = sqrt(-8); 
17         printf("%lf
",t);
18         while(n--) {
19             int m;
20             scanf("%d",&m);
21             for(int i = 0; i < m; i++) {
22                 scanf("%lf",&r[i]);
23             }
24             sort(r,r+m,cmp);
25             int cnt = 0;
26             double total = 0;
27             while(total < 20) {
28                 total += sqrt(r[cnt]*r[cnt]-1*1)*2;
29                 cnt++;
30             }
31             printf("%d
", cnt);
32         }
33     }
34     return 0;
35 }

原文地址:https://www.cnblogs.com/jasonJie/p/6084712.html