HDU6354 Everything Has Changed 多校第五场 几何题
爱德华是铝循环机械的工人。他的工作是操作机械臂来切割设计模型。以下是他的工作简介。
假设操作平面为二维坐标系。首先,有一个带中心坐标的圆盘(0 ,0 ) 和半径 [R。然后,米 机械臂将同时削减和擦除其影响范围内的所有内容。区域是具有中心坐标的圆和半径 。为了获得可观的模型,保证每两个切割区域没有交叉,并且没有切割区域包含整个盘。
您的任务是确定光盘剩余区域的周长,不包括内部周长。
以下是样本的图示,其中红色曲线计算但绿色曲线不计算。
The first line contains one integer T, indicating the number of test cases.
The following lines describe all the test cases. For each test case:
The first line contains two integers m and R.
The i-th line of the following m lines contains three integers xi,yi and ri, indicating a cutting area.
1≤T≤1000, 1≤m≤100, −1000≤xi,yi≤1000, 1≤R,ri≤1000 (i=1,2,⋯,m).
对于每个测试用例,在一行中打印剩余区域的周长。如果绝对或相对误差不超过,则认为您的答案是正确的10- 6。
如果您的答案被认为是正确的| a-b |max (1 ,| b |)≤ 10- 6。
[解题思路]
利用余弦定理 再用acos函数得到角度 th*r得到变动周长 res+=即可。
保留20位小数是个大坑
判断圆相切相离相交就是考察大家初中数学知识啦
还有比赛过程中debug的 “==” 和 “double” 都是我和我的搭档感觉超级坑的东东
[AC代码]
#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#define IO; std::ios::sync_with_stdio(false);std::cin.tie(0);
//降低输入输出时间
using namespace std;
const double PI = acos(-1);
struct NNN{
int x;
int y;
int r;
};
NNN circle[105];
int judge(double d,int R,int r)//d距离
{
if(d>(r+R)||d<abs(R-r)) return 0;//不相交
if(d<(r+R)&&d>abs(R-r)) return 1;//正常相交
if(d==(r+R)) return 2;//外交
if(d==abs(R-r)) return 3;//内交
}
double redis(int x,int y)
{
return sqrt(x*x+y*y);
}
/************************/
double recosr(int r,int R,double l)
{
//cout<<"thr"<<(r*r+l*l-R*R)*1.0/(2*r*l)<<endl;
//cout<<"acos"<<acos((r*r+l*l-R*R)*1.0/(2*r*l))<<endl;
return acos((r*r+l*l-R*R)*1.0/(2*r*l));
}
double recosR(int r,int R,double l)
{
//cout<<"thr"<<(r*r+l*l-R*R)*1.0/(2*r*l)<<endl;
//cout<<"acos"<<acos((r*r+l*l-R*R)*1.0/(2*r*l))<<endl;
return acos((R*R+l*l-r*r)*1.0/(2*R*l));
}
int main()
{
IO;
/**输入**/
int T;
cin>>T;
while(T--)
{
int m,R;
cin>>m>>R;
double res=2*PI*R;
NNN onlyc;
onlyc.r=m;onlyc.x=0;onlyc.y=0;
for(int i=0;i<m;i++)
{
cin>>circle[i].x>>circle[i].y>>circle[i].r;
}
for(int i=0;i<m;i++)
{
double LL=redis(circle[i].x,circle[i].y);
if(judge(LL,R,circle[i].r)==0) {continue;}
else if(judge(LL,R,circle[i].r)==1)
{
//cout<<"相交"<<endl;
double thr=recosr(circle[i].r,R,LL);
double thR=recosR(circle[i].r,R,LL);
res+=(-2*thR*R+2*thr*circle[i].r);
}
else if(judge(LL,R,circle[i].r)==3){
//cout<<"相切"<<endl;
res+=2*PI*circle[i].r;
}
else {
continue;
}
}
cout.setf(ios::fixed);
cout <<fixed<<setprecision(20) <<res<<endl;
}
}