首页 > 其他 > 详细

一本通 1.1 例 3【喷水装置】

时间:2020-10-25 17:54:06      阅读:40      评论:0      收藏:0      [点我收藏+]

题目linkhttps://loj.ac/problem/10002

首先这道题不是用中心点 $+$ 半径作为一个区间的,可以发现如果那样算的话,圆与圆之间可能还会有一个缝隙,所以应该用勾股定理求出每一个圆所覆盖的区间,注意一下上下的距离够不够,然后就是区间覆盖问题,直接贪心即可。$O(n$2$)$

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 using namespace std;
 4 int T, n, l, w, num;
 5 struct Str {double l, r;}stu[15010];
 6 int cmp(Str a, Str b) {return a.l == b.l ? a.r > b.r : a.l < b.l;}
 7 double cal(int R) {return (double)sqrt(R * R * 1.0 - w * w * 1.0 / 4);}
 8 int main()
 9 {
10     scanf("%d", &T);
11     while(T--)
12     {
13         num = 0;
14         scanf("%d %d %d", &n, &l, &w);
15         for(int i = 1, x, R; i <= n; ++i)
16         {
17             scanf("%d %d", &x, &R); if(2 * R < w) continue;
18             stu[++num].l = x * 1.0 - cal(R), stu[num].r = x * 1.0 + cal(R);
19             if(stu[num].l < 0) stu[num].l = 0; if(stu[num].r > l) stu[num].r = l;
20         }
21         sort(stu + 1, stu + num + 1, cmp); if(stu[1].l > 0) {puts("-1"); continue;}
22         double end = 0; int ans = 0;
23         for(int i = 0; ; ++ans)
24         {
25             if(end >= l) break; 
26             int change = 0; double maxe = end;//注意这里maxe是double!
27             for(int j = i + 1; j <= num; ++j)
28             {
29                 if(stu[j].l > end) break;
30                 if(stu[j].r > maxe) maxe = stu[j].r, i = j, change = 1; 
31             }
32             end = maxe; 
33             if(!change) break;
34         }
35         if(end < l) puts("-1"); else printf("%d\n", ans);
36     }
37     return 0;
38 }

 

一本通 1.1 例 3【喷水装置】

原文:https://www.cnblogs.com/qqq1112/p/13873925.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!