POJ--3808(几何,二分)

2015-04-13 21:52:25

思路:Japan 2009 的题... (Japan果然老喜欢几何了...- -)

  题意很精简,在一个三角形内嵌入三个圆,每个角对应一个圆。已知三角形三个点的坐标,求三个圆的半径。

  蒟蒻不会.. 看的红书的思路...

  ※我们可以二分枚举一个圆的半径 r1,然后根据下图,可以列出方程:

  r1/tanα + r2/tanβ + sqrt((r1+r2)^2 - (r1-r2)^2) = AB

  可以二分一下 r2 来求出 r2,同理可以求出 r3。然后把求出的 r2,r3 带入类似的方程,

  判断其 > BC 还是 < BC,若小于说明r2,r3过小,r1应该缩小;若大于说明r2,r3过大,r1应该扩大。

  当然有直接数学推出公式的方法... 蒟蒻还不会... 待补!~

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=0;i<(n);++i)
17 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
18 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
19 #define MP(a,b) make_pair(a,b)
20 
21 typedef long long ll;
22 typedef pair<int,int> pii;
23 const int INF = (1 << 30) - 1;
24 const double eps = 1e-12;
25 const double PI = acos(-1.0);
26 
27 double X1,Y1,X2,Y2,X3,Y3;
28 double AB,BC,AC,r1,r2,r3;
29 double A,B,C,tHA,tHB,tHC;
30 
31 double Dis(double a1,double b1,double a2,double b2){
32     return sqrt((a1 - a2) * (a1 - a2) + (b1 - b2) * (b1 - b2));
33 }
34 
35 double sign(double v){
36     if(fabs(v) < eps) return 0;
37     return v < -eps ? -1 : 1;
38 }
39 
40 void Pre(){
41     A = acos((AB*AB + AC*AC - BC*BC) / (2*AB*AC));
42     B = acos((AB*AB + BC*BC - AC*AC) / (2*AB*BC));
43     C = acos((BC*BC + AC*AC - AB*AB) / (2*BC*AC));
44     tHA = tan(A / 2.0);
45     tHB = tan(B / 2.0);
46     tHC = tan(C / 2.0);
47 }
48 
49 double F(double ra,double ta,double rb,double tb,double L){
50     return ra*tb + 2.0*ta*tb*sqrt(ra*rb) + rb*ta - L*ta*tb;
51 }
52     
53 bool Judge(double v){ //可扩大
54     r1 = v;
55     double l = 0.0,r = 2000.0;
56     while(sign(r - l) != 0){
57         double mid = getmid(l,r);
58         if(sign(F(r1,tHA,mid,tHB,AB)) < 0) l = mid + eps;
59         else r = mid - eps;
60     }
61     r2 = l;
62     l = 0.0,r = 2000.0;
63     while(sign(r - l) != 0){
64         double mid = getmid(l,r);
65         if(sign(F(r1,tHA,mid,tHC,AC)) < 0) l = mid + eps;
66         else r = mid - eps;
67     }
68     r3 = l;
69     if(sign(F(r2,tHB,r3,tHC,BC)) < 0) return false;
70     return true;
71 }
72 
73 int main(){
74     while(scanf("%lf%lf%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2,&X3,&Y3) != EOF){
75         if(X1==0 && Y1==0 && X2==0 && Y2==0 && X3==0 && Y3==0) break;
76         AB = Dis(X1,Y1,X2,Y2);
77         BC = Dis(X2,Y2,X3,Y3);
78         AC = Dis(X1,Y1,X3,Y3);
79         Pre();
80         double l = 0.0,r = 2000.0;
81         while(sign(r - l) != 0){
82             double mid = getmid(l,r);
83             if(Judge(mid)) l = mid + eps;
84             else r = mid - eps;
85         }
86         printf("%.6f %.6f %.6f\n",r1,r2,r3);
87     }
88     return 0;
89 }

 

posted @ 2015-04-13 22:20  Naturain  阅读(157)  评论(0编辑  收藏  举报