题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3806
题目大意:给一个三角形的外接圆半径以及内切圆半径,求满足给出条件的三角形的三条边。
题目给出的样例有点坑.......容易误导人
Sample Input
1 2 2 5 9 9
Sample Ouput
3.464101615137754587 3.464101615137754587 3.464101615137754587 6 8 10 NO Solution!
给出的2和5的例子的时候其答案给出的是三个整数。所以会有点误导。
最开始看见题目的时候被样例误导了,一直没有什么思路,后来在纸上画了很久发现了一个特例。
YY给出的内切圆和外切圆的圆心是在一个直线上面的,然后是可以根据正弦定理以及一系列的变形得到长度x和角度α之间的关系。
然后数学公式可以得出:角度α和x的公式为
x =( 1 + 1 / sin(α) )/ (2 - 2*sin(α)*sin(α))
根据公式二分sin(α)
sin(α)的取值范围是0~1,比较与输入x 的大小,重新确定上界下界。(此函数是一个递增的)
求得sin(α)后可以根据x的大小以及α角度一些关系得到三角形的三条边。
注意变换之后默认的内切圆半径是1,故求得的三角形三边要乘于R/r
#include<iostream>
#include<math.h>
#include<cstring>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define eps 1e-11
double er(double x)
{
double l = 0, r = 1, mid;
while(l<r){
mid = (l+r)/2;
//printf("%.9lf %.9lf\n",l,r);
double temp = (1.0+1.0/mid)/(2.0-2.0*(mid*mid));
if(temp-x>eps) l = mid;
else if(temp+eps<x) r = mid;
else break;
}
//printf("%.13lf\n",mid);
return mid;
}
int main ()
{
double n,m;
while(~scanf("%lf %lf",&n,&m)){
double bi=m/n;
if((bi-2)<-eps) {printf("NO Solution!\n");continue;}
double sinx=er(bi);
double cosx=sqrt(1-sinx*sinx);
double y = (1.0 + 1.0/sinx)/cosx;
double t = (1.0+sinx)/cosx;
printf("%.18lf %.18lf %.18lf\n",y*n,y*n,2*t*n);
}
}
忽略我的函数名称定义以及...... 出现的一个er(bi) ........