给这个题跪了。。。
比赛的时候一直在交,从没停下wa的脚步...
因为这个题目说明了判题的时候是判断能否由输出得到输入
所以我想到这个题一个输入可能对应很多解,但我只需要输出一组可行解就行了
于是自然而然的想到把所有的解抽象成等边三角形,于是就各种WA
后来群里面说应该抽象为等腰三角形,说是什么有可行解就一定有等腰解
但是并没有证明,也不知道他们是怎么想到的...
二分的步骤是:
设三角形两腰为a,底边成为c,内切圆半径r1,外接圆半径r2
二分枚举c,判断何时a同时满足r1,r2
因为有公式S=abc/4r2,现在设等腰三角形高为h
则S=h*c/2,所以h*c/2==a*a*c/4r2
得到a^2 = 2hr2,再由a^2 = h^2 + c^2
可以得到一元二次方程h^2-2hr2+c*c/4 = 0
通过通项公式解出h=r2+sqrt(r2*r2-c*c/4)
进而求出a
接着再通过r1求a:
可以知道h分为两段,一段为r1,另一段长度为sqrt( (a-c/2)*(a-c/2) + r1*r1 )
则h = r1+sqrt( (a-c/2)*(a-c/2) + r1*r1 )
进而求出a
再判断 + 二分
代码基本上是看别人的写的:
#include <bits/stdc++.h>
#define LL long long
#define eps 1e-10
using namespace std;
int sgn(double x) {//这个东西的用法很奇葩
return (x>eps)-(x<-eps);
}
int main(void) {
double r1, r2, L, R, M, a, c, h;
while(scanf("%lf%lf", &r1, &r2) != EOF) {
if(sgn(r2-2*r1) >= 0) {
L = 0.0, R = sqrt(3.0)*r2;
while(R-L > eps) {
c = (L+R) / 2;
h = r2+( sqrt(r2*r2-c*c/4.0) );
a = sqrt(h*h+c*c/4.0);
if( sgn(c*c/4.0+pow( r1 + sqrt(r1*r1+(a-c/2.0)*(a-c/2.0)) , 2.0) - a*a) < 0 ) {
R = c;
} else L = c;
}
c = L;
h = r2+( sqrt(r2*r2-c*c/4.0) );
a = sqrt(h*h+c*c/4.0);
printf("%.15lf %.15lf %.15lf\n", a, a, c);
}
else printf("NO Solution!\n");
}
return 0;
}