码迷,mamicode.com
首页 > 其他好文 > 详细

[HAOI2008] 下落的圆盘 - 计算几何

时间:2020-03-01 14:03:32      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:mamicode   double   cpp   tor   lag   tin   void   范围   class   

技术图片

Solution

技术图片

我又忘记了 atan2 可以自动处理角度范围555

#include <bits/stdc++.h>
using namespace std;

const int N = 10005;
const double pi = 3.14159265358979;
const double eps = 1e-6;

namespace solver {
    vector <pair<double,int> > v;
    void clear() {
        v.clear();
    }
    void make(double x,double y) {
        v.push_back({x,1});
        v.push_back({y,0});
    }
    double solve() {
        make(0,0);
        make(2*pi,2*pi);

        int cnt=0;
        double ans=0,last=0;
        sort(v.begin(),v.end());
        for(pair<double,int> pr:v) {
            double p=pr.first;
            int w=pr.second;
            if(cnt==0) ans+=p-last;
            last=p;
            if(w==1) cnt++;
            if(w==0) cnt--;
        }
        return ans;
    }
}

int n;
double x[N],y[N],r[N];

double calc(double x) {
    while(x<0) x+=pi*2;
    while(x>pi*2) x-=pi*2;
    return x;
}

signed main() {
    cin>>n;
    for(int i=1;i<=n;i++) cin>>r[i]>>x[i]>>y[i];
    double ans=0;
    for(int i=1;i<=n;i++) {
        double x0=x[i],y0=y[i],r0=r[i];
        solver::clear();
        int flag=0;
        for(int j=i+1;j<=n;j++) {
            double D=sqrt(pow(x[j]-x0,2)+pow(y[j]-y0,2));
            if(D<=r[j]-r0) flag=1;
        }
        if(flag) continue;
        for(int j=i+1;j<=n;j++) {
            double D=sqrt(pow(x[j]-x0,2)+pow(y[j]-y0,2));
            if(D>=r0+r[j]) continue;
            double theta = atan2(y[j]-y0,x[j]-x0);
            theta=calc(theta);
            double phi = acos((D*D+r0*r0-r[j]*r[j])/(2*D*r0));
            double a1 = calc(theta+phi);
            double a2 = calc(theta-phi);
            if(fabs(a2-a1)>eps) {
                if(a1>a2) {
                    solver::make(a2,a1);
                }
                else {
                    solver::make(a2,2*pi);
                    solver::make(0,a1);
                }
            }
        }
        double tmp=solver::solve();
        ans+=tmp*r0;
    }
    printf("%.3lf\n",ans);
}

[HAOI2008] 下落的圆盘 - 计算几何

标签:mamicode   double   cpp   tor   lag   tin   void   范围   class   

原文地址:https://www.cnblogs.com/mollnn/p/12389328.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!