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;
}
}