又是计算几何的二分题。
以后遇到这种题真应该往二分想。
详细解释 http://www.csdn123.com/html/topnews201408/70/970.htm
自己做的时候 思维定势了。 总是从三角形出发 画圆了。 忘记了 两个圆可以随意放位置了。
三个点可以由外接圆确定。然后改变三点的位置。 使内切圆正好可以放上。
这样可以确定顶点,让下面两个点不确定。 那么就可以枚举下面两个点连线的长度了。
在计算过程中会发现。枚举底边长度一半简单。
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 1000000+10
#define INF (1<<30)
#define mod 123456789
double eps = 1e-10;
int main (){
double r,R;
while(scanf("%lf%lf",&r,&R) != EOF){
if(r*2.0 > R)
printf("NO Solution!\n");
else{
double left = 0, right = sqrt(3.0)*R/2; // 底边一半最长的长度
double mid;
double h,H;
double bian;
while(right-left > eps){
mid = (left+right)/2.0;
h = sqrt(R*R-mid*mid);
H = h+R; // 底边高
bian = sqrt(H*H+mid*mid); // 等腰三角形的边长
double rr = (H*mid)/(bian+mid); // 根据三角形来确定的内切圆的半径。用的等面积求高的方法来求半径
if(rr < r)
left = mid;
else
right = mid;
}
printf("%.10lf %.10lf %.10lf\n",mid*2,bian,bian);
}
}
return 0;
}