zoukankan      html  css  js  c++  java
  • bzoj 1043[HAOI2008]下落的圆盘

    1043: [HAOI2008]下落的圆盘

    Time Limit: 10 Sec  Memory Limit: 162 MB

    Description

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

    Input

      第一行为1个整数n,N<=1000
    接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标.

    Output

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

    Sample Input

    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;
     22 inline LL read()
     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
    ", 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 {
    107     N = read();
    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
    ", ans);
    115     return 0;
    116 }
    117 
    118 /*
    119 
    120 2
    121 
    122 1 0 0
    123 
    124 1 1 0
    125 */
    View Code
  • 相关阅读:
    MySQL运维案例分析:Binlog中的时间戳
    身边有位“别人家的程序员”是什么样的体验?
    苹果收取30%过路费_你是顶是踩?
    1019 数字黑洞 (20 分)C语言
    1015 德才论 (25 分)C语言
    1017 A除以B (20 分)C语言
    1014 福尔摩斯的约会 (20 分)
    求n以内最大的k个素数以及它们的和、数组元素循环右移问题、求最大值及其下标、将数组中的数逆序存放、矩阵运算
    1005 继续(3n+1)猜想 (25 分)
    爬动的蠕虫、二进制的前导的零、求组合数、Have Fun with Numbers、近似求PI
  • 原文地址:https://www.cnblogs.com/wuenze/p/8570450.html
Copyright © 2011-2022 走看看