标签:
http://codeforces.com/problemset/problem/77/E
如图,给出黑圆的半径 R 和黄圆的半径 r,再给出一个整数 k,表示画 k 个绿色的圆,问最小一个圆的半径。
上面的第一幅图是 R = 4, r = 3, k = 1 的状况。
第二幅图是 R = 4, r = 2, k = 2 的状况。
每个测试点有不超过 10000 组数据。每组数据的 k 不超过 10000。
以黄圆和黑圆的切点为原点,切线方向为 y 轴,对图形进行几何反演,黄圆和黑圆变成两条平行直线,粉色和绿色的圆在平行线之间,就容易求得第 k 个圆的圆心和半径,然后再反演一次,得到答案。
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 5 #include <algorithm> 6 #include <iostream> 7 8 const double T = 100; 9 10 double sqr(double x) { return x * x; } 11 12 struct Point 13 { 14 double x, y; 15 16 Point(double xi, double yi): x(xi), y(yi) {} 17 18 Point(Point p, double r) 19 { 20 double d = p.dis(); 21 x = p.x / d * r; 22 y = p.y / d * r; 23 } 24 25 double dis() const { return sqrt(x * x + y * y); } 26 }; 27 28 struct Circle 29 { 30 Point mid; 31 double r; 32 33 Circle(Point midi, double ri): mid(midi), r(ri) {} 34 }; 35 36 37 double inversion(const Circle& c) 38 { 39 double h = c.mid.dis(); 40 double r = c.r; 41 return r * T / (sqr(h) - sqr(r)); 42 } 43 44 double inversion(Point p, double r) { return inversion(Circle(p, r)); } 45 46 int main() 47 { 48 int casc; 49 scanf("%d", &casc); 50 for (int casi = 1; casi <= casc; casi++) { 51 double r, R; 52 int k; 53 scanf("%lf %lf", &R, &r); 54 scanf("%d", &k); 55 Point p1(T / 2 / r, 0); 56 Point p2(T / 2 / R, 0); 57 double x = (R - r) * T / 4 / r / R; 58 printf("%.10f\n", inversion(Point(T * (R + r) / 4 / R / r, 2 * k * x), x)); 59 } 60 return 0; 61 }
标签:
原文地址:http://www.cnblogs.com/gu-castle/p/4963274.html