[HAOI2008] 下落的圆盘 - 计算几何
Posted mollnn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HAOI2008] 下落的圆盘 - 计算几何相关的知识,希望对你有一定的参考价值。
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
",ans);
}
以上是关于[HAOI2008] 下落的圆盘 - 计算几何的主要内容,如果未能解决你的问题,请参考以下文章