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

Solution

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

我又忘记了 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);
}

相关文章:

  • 2022-12-23
  • 2021-07-08
  • 2021-11-27
  • 2022-01-30
  • 2021-07-15
  • 2021-08-10
猜你喜欢
  • 2021-11-14
  • 2021-07-28
  • 2022-12-23
  • 2022-02-04
  • 2021-06-10
相关资源
相似解决方案