1. 程式人生 > >【計算幾何】【圓反演】hdu6158 The Designer

【計算幾何】【圓反演】hdu6158 The Designer

using 技術分享 技術 幾何 ++i %d mat 圓的面積 logs

技術分享

給你內外那倆圓的半徑,讓你按圖中標號的順序往縫裏塞n個小圓,問你小圓的總面積。

不知道圓反演的先去查一下定義。

將兩個圓的切點視作反演中心,任取反演半徑(比如1),將兩個圓反演成兩條平行直線,則那些小圓都變成相同大小啦!就很好算了,我們再將小圓通過反演算回它原來的面積即可。

技術分享

怎樣求原小圓的面積呢?

技術分享

只需求得AB的長度即可。因為A’距離原點的距離我們知道,B’距離原點的距離我們也知道,OA,OB就很好求了,作個差就是AB。

(這套CCPC網絡賽的題是我們學校的人出的,線下測題的時候,我的這份代碼能AC的,現在我交到hdu上就TLE了,貌似加強了數據,卡了常數……?)

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double PI=acos(-1.0);
int R1,R2,n;
double sqr(double x){
	return x*x;
}
int T;
int main(){
	//freopen("e.in","r",stdin);
	scanf("%d",&T);
	for(;T;--T){
		scanf("%d%d%d",&R1,&R2,&n);
		if(R1>R2){
			swap(R1,R2);
		}
		double r=(1.0/2.0/(double)R1-1.0/2.0/(double)R2)*0.5;
		double X=(1.0/2.0/(double)R1+1.0/2.0/(double)R2)*0.5;
		double now=0,ans=0;
		for(int i=1;i<=n;++i){
			double t=sqrt(X*X+now*now);
			ans+=sqr((1.0/(t-r)-1.0/(t+r))*0.5)*PI;
			if(i&1){
				now+=r*2.0;
			}
		}
		printf("%.5lf\n",ans);
	}
	return 0;
}

【計算幾何】【圓反演】hdu6158 The Designer