# bzoj 1043[HAOI2008]下落的圆盘 - 贪心 + 几何

## 1043: [HAOI2008]下落的圆盘

Time Limit: 10 Sec  Memory Limit: 162 MB

## Description

有n个圆盘从天而降，后面落下的可以盖住前面的。求最后形成的封闭区域的周长。看下面这副图, 所有的红

## Input

第一行为1个整数n,N<=1000

最后的周长，保留三位小数

2
1 0 0
1 1 0

## Sample Output

10.472

  1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #include <cmath>
6 #define LL long long
7 #define pi acos(-1.0)
8 using namespace std;
9
10 const int MAXN = 1e3 + 10;
11 LL N;
12 double ans;
13 struct circle {
14     double x, y;
15     double r;
16 } c[MAXN];
17
18 struct seg {
19     double l, r;
20 } s[MAXN * 5];
21 double thita1, thita2;
23 {
24     LL x = 0, w = 1; char ch = 0;
25     while(ch < '0' || ch > '9') {
26         if(ch == '-') {
27             w = -1;
28         }
29         ch = getchar();
30     }
31     while(ch >= '0' && ch <= '9') {
32         x = x * 10 + ch - '0';
33         ch = getchar();
34     }
35     return x * w;
36 }
37
38 double dis(int i, int j)
39 {
40     return sqrt((c[i].y - c[j].y) * (c[i].y - c[j].y) + (c[i].x - c[j].x) * (c[i].x - c[j].x));
41 }
42
43 bool con(int i, int j, double d)
44 {
45     if(d + c[i].r <= c[j].r) {
46         return true;
47     }
48     return false;
49 }
50
51 bool cmp(seg a, seg b)
52 {
53     if(a.l == b.l) {
54         return a.r >= b.r;
55     }
56     return a.l < b.l;
57 }
58
59 void cal(int i)
60 {
61     int tot = 0;
62     for(int j = i + 1; j <= N; j++) {
63         double d = dis(i, j);
64         if(con(i, j, d)) {
65             return;
66         }
67         double l, r;
68 //        cout<<d<<endl;
69         if(d <= c[i].r + c[j].r && !con(j, i, d)) {
70             thita1 = atan2(c[j].y - c[i].y, c[j].x - c[i].x);
71             thita2 = acos((d * d + c[i].r * c[i].r - c[j].r * c[j].r) / (2 * d * c[i].r));
72     //    cout<<thita1<<" "<<thita2<<endl;
73             l = thita1 - thita2, r = thita1 + thita2;
74         //    printf("%.3lf %.3lf\n", l, r);
75             if(l < 0) {
76                 l = l + 2 * pi;
77             }
78             if(r < 0) {
79                 r = r + 2 * pi;
80             }
81             if(l > r) {
82                 s[tot].l = l;
83                 s[tot++].r = 2 * pi;
84                 s[tot].l = 0;
85                 s[tot++].r = r;
86             } else {
87                 s[tot].l = l;
88                 s[tot++].r = r;
89             }
90         }
91     }
92     sort(s, s + tot, cmp);
93     double len = 0, cnt = 0;
94     for(int j = 0; j < tot; j++) {
95 //        cout<<s[j].l<<" "<<s[j].r<<endl;
96         if(s[j].l > cnt) {
97             len += s[j].l - cnt;
98         }
99         cnt = max(cnt, s[j].r);
100     }
101     len += 2 * pi - cnt;
102     ans += len * c[i].r;
103     //cout<<len<<endl;
104 }
105 int main()
106 {
108     for(int i = 1; i <= N; i++) {
109         scanf("%lf%lf%lf", &c[i].r, &c[i].x, &c[i].y);
110     }
111     for(int i = 1; i <= N; i++) {
112         cal(i);
113     }
114     printf("%.3lf\n", ans);
115     return 0;
116 }
117
118 /*
119
120 2
121
122 1 0 0
123
124 1 1 0
125 */
View Code

posted @ 2018-03-14 22:05  大财主  阅读(305)  评论(0编辑  收藏  举报