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

    有 n 个圆盘从天而降,后面落下的可以盖住前面的。最后按掉下的顺序,在平面上依次测得每个圆盘的圆心和半径,问下落完成后从上往下看,整个图形的周长是多少,即你可以看到的圆盘的轮廓的圆盘的轮廓总长.例如下图的黑色线条的总长度即为所求。

    【输入格式】

    第一行为1个整数n

    接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标.

    【输出格式】

    仅一个实数,表示所求的总周长,答案保留3位小数.

    【样例输入】

    2
    1 0 0
    1 1 0
    

    【样例输出】

    10.472

    【提示】

    30%的数据,n<=10

    100%的数据,n<=1000

    数学问题 计算几何

    用余弦定理和三角函数可以计算出两圆相交部分的弧长。

    对于每个圆,计算它和在它之后落下的所有圆的角。记录相交部分的弧对应的圆心角范围。将“圆心角”区间离散到0~2pi的数轴上,做线段覆盖。

    知道了未被覆盖的角总共有多大,就能算出该圆未被覆盖的弧有多长。

    注意如果求出的覆盖部分圆心角范围超出了0~2pi,要变换到0~2pi范围内

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<vector>
     7 using namespace std;
     8 const double pi=acos(-1.0);
     9 const double eps=1e-7;
    10 const int mxn=1010;
    11 struct point{
    12     double x,y;
    13     point operator + (point b){return (point){x+b.x,y+b.y};}
    14     point operator - (point b){return (point){x-b.x,y-b.y};}
    15     double operator * (point b){return x*b.x+y*b.y;}
    16 };
    17 inline double Cross(point a,point b){
    18     return a.x*b.y-a.y*b.x;
    19 }
    20 inline double dist(point a,point b){
    21     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    22 }
    23 inline double Len(point a){return sqrt(a*a);}
    24 struct cir{
    25     double x,y;
    26     double r;
    27     point operator + (cir b){return (point){x+b.x,y+b.y};}
    28     point operator - (cir b){return (point){x-b.x,y-b.y};}
    29 }c[mxn];
    30 inline bool cover(cir a,cir b){
    31     return (a.r>=b.r+Len(a-b));
    32 }
    33 struct line{
    34     double l,r;
    35     bool operator < (line b)const{
    36         return (l<b.l)|| (l==b.l && r<b.r);
    37     }
    38 };
    39 line CX(cir a,cir b){
    40     double dis=Len(b-a);
    41     double angle=acos((a.r*a.r+dis*dis-b.r*b.r)/(2*a.r*dis));
    42     double deg=atan2(a.x-b.x,a.y-b.y);//统一旋转pi角度,保证在-2pi~2pi范围内
    43     return (line){deg-angle,deg+angle};
    44 /*    double t=(a.r*a.r+dis*dis-b.r*b.r)/(2*dis);
    45     double st=atan2(a.x-b.x,a.y-b.y);
    46     double l=acos(t/a.r);
    47     return (line){st-l,st+l};*/
    48 }
    49 vector<line>ve;
    50 int n;
    51 double ans=0;
    52 void calc(int x){
    53     for(int i=x+1;i<=n;i++){if(cover(c[i],c[x]))return;}//被完全覆盖 
    54     ve.clear();
    55     for(int i=x+1;i<=n;i++){
    56         if(cover(c[x],c[i]))continue;//完全覆盖
    57         line tmp;
    58         if(c[x].r+c[i].r>Len(c[i]-c[x])) tmp=CX(c[x],c[i]);
    59         else continue;
    60         if(tmp.l<0) tmp.l+=2*pi;
    61         if(tmp.r<0) tmp.r+=2*pi;
    62         if(tmp.l>tmp.r){//拆分 
    63             ve.push_back((line){0,tmp.r});
    64             ve.push_back((line){tmp.l,2*pi});
    65         }
    66         else ve.push_back(tmp);
    67     }
    68     sort(ve.begin(),ve.end());
    69 //    printf("mid
    ");
    70     double now=0,ran=0;
    71     for(int i=0;i<ve.size();i++){//线段覆盖 
    72         line tmp=ve[i];
    73 //        printf("i:%d %.3f %.3f
    ",i,tmp.l,tmp.r);
    74         if(tmp.l>now){ran+=tmp.l-now;now=tmp.r;}
    75         else now=max(now,tmp.r);
    76     }
    77     ran+=2*pi-now;
    78     ans+=c[x].r*ran;//累加半径 
    79     return;
    80 }
    81 int main(){
    82     freopen("disc.in","r",stdin);
    83     freopen("disc.out","w",stdout);
    84     int i,j;
    85     scanf("%d",&n);
    86     for(i=1;i<=n;i++){
    87         scanf("%lf%lf%lf",&c[i].r,&c[i].x,&c[i].y);
    88     }
    89     for(i=n;i>=1;i--){
    90         calc(i);
    91 //        printf("ans:%.3f
    ",ans);
    92     }
    93     printf("%.3f
    ",ans);
    94     return 0;
    95 }
  • 相关阅读:
    python模块—socket
    mac os系统的快捷键
    教你如何将UIImageView视图中的图片变成圆角
    关于ASP.NET MVC
    iOS 日期格式的转换
    将App通过XCode上传到AppStore 出现这个错误“An error occurred uploading to the iTunes Store”的解决方法
    关于MAC OS下面两个软件的功能改进——Dictionary和Fit 输入法
    分享一下上个星期的香港行程
    【博客园IT新闻】博客园IT新闻 iPhone 客户端发布
    解决Entity Framework Code First 的问题——Model compatibility cannot be checked because the database does not contain model metadata
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6676170.html
Copyright © 2011-2022 走看看