Hdu 4773,13杭州D(幾何,圓的反演)

2022-05-24 15:33:11 字數 3024 閱讀 6063

2015-02-24 16:06:13

這道題乍一看能直接數學搞... (就交給mo神犇吧...)

關於幾何反演基礎知識,推薦兩篇博文:博文1,博文2

從一維反演推廣而來的圓反演有蠻多性質,這題我們要關注:

(1)過反演中心的圓,反形為不過反演中心的直線。    

(2)不過反演中心的直線,反形為過反演中心的圓。

例1

例2

(圖中(0,0)為反演中心,藍色圓為反演圓,綠色直線和棕色圓互為反形)

(3)不過反演中心的圓,反形也為不過反演中心的圓。

(圖中綠色圓與黃色圓互為反形)

(4)反演不改變相切性。(定理:相切兩圓的反象仍相切,若切點恰是反演中心,則其反象為兩平行線)

其實(1)與(2)互逆,(4)也可證。

思路:首先我們把給定的p點看做反演中心,然後自定義反演半徑的大小(為保證精度,不宜過小),這樣我們就得到了反演圓 c(p,r)

接著,求出題目給出的兩個圓c1,c2各自的反形c1』,c2』。

然後,作出c1』和c2』的外公切線,再將公切線反演回去就得到答案所需的圓了。

(依據:根據(4)的定理,我們倒著考慮,最終的圖形為3個圓,答案圓與另外兩圓外切,如果將這三個圓反演回去,答案圓因為過反演中心,所以反形是一條直線,

另外兩個題目給出的圓因為沒有過反演中心,所以反形是兩個圓,由於相切性不變,這條直線與這兩個反形圓均相切,即為公切線。)

注意:不僅要求的是公切線,為了防止出現內切的情況,我們要求的是「外公切線」,並且要使得p點和反形圓的圓心在外公切線的同一側。

這個當時很不理解... 所以畫了個圖,p(0,0),兩個大圓相距很近(這裡暫時讓他們相交,只為說明問題),他們的反形為兩個很近的小圓,兩條外公切線如圖。

(1)對於紅外公切線y=1/6,p點和小圓圓心在公切線異側,公切線的反形(x^2+(y-3)^2=9)會內切大圓。

(2)對於綠外公切線y=1/2,p點和小圓圓心在公切線同側,公切線的反形(x^2+(y-1)^2=1)會外切大圓。

由此,當p點和反形圓的圓心在外公切線的同一側時,該外公切線才是符合要求的。

最後,將公切線反演回去就比較方便了,求出p點到直線距離,然後就可就出答案圓的半徑,至於答案圓的圓心可以用向量相似解決。

(a了好久... 如有錯誤,還望指出)

1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 

8 #include 9 #include 10 #include

11 #include 12 #include 13

using

namespace

std;

1415

#define mem(a,b) memset(a,b,sizeof(a))

16#define rep(i,n) for(int i=1;i<=(n);++i)

17#define rev(i,n) for(int i=(n);i>=1;--i)

18#define for(i,a,b) for(int i=(a);i<=(b);++i)

19#define rfor(i,a,b) for(int i=(a);i>=(b);--i)

20#define getmid(l,r) ((l) + ((r) - (l)) / 2)

21#define mp(a,b) make_pair(a,b)

2223 typedef long

long

ll;24 typedef pairpii;

25const

int inf = (1

<< 30) - 1;26

const

double eps = 1e-10;27

28double add(double a,double b)

3233

struct

point

36 point operator +(point p)

39 point operator -(point p)

42 point operator * (double

d)45 point operator / (double

d)48 point move(double a,double

d)51

void

read()

54};

5556

struct

circle

60void

read()

64void

out()

67};

6869

int sign(double x)

7273

double cross(point a,point b,point c)

7677

double

dis(point a,point b)

8081 circle c[5

];82

point p;

83int

t,tot;

84double

r;85

86 circle inver(circle c1)

9697

void mark(point a,point b)

104105

void

solve()

118119

intmain()

130return0;

131 }

hdu1285 hdu4857 拓撲排序

一 原題內容 problem description 有n個比賽隊 1 n 500 編號依次為1,2,3,n進行比賽,比賽結束後,裁判委員會要將所有參賽隊伍從前往後依次排名,但現在裁判委員會不能直接獲得每個隊的比賽成績,只知道每場比賽的結果,即p1贏p2,用p1,p2表示,排名時p1在p2之前。現在...

樹狀陣列 hdu2689 hdu2838

題意 給定乙個正整數n,和乙個1 n的乙個排列,每個數可以和旁邊的兩個數的任意乙個交換,每交換一次總次數就要加一,問將這個排列轉換成乙個遞增的排列需要多少次交換?題意可以轉換成求這個排列的逆序對數。include include include include using namespace std...

hdu2068 hdu 2049 錯排組合

這部分涉及的知識為組合數和錯排 參考 比較簡單 hdu2068 include include int64 c int n,int m 組合數公式 return u d main sum for i 3 i 13 i f i i 1 f i 1 f i 2 while scanf d n n 另一題...