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 }