http://codeforces.com/gym/102007/attachments
给四个整数a,b,c,d组成一个四边形,求四边形面积的最大值,保证有解。
法一:
容易证明,对一个四个边长一定的四边形,随着某条对角线的长度变化是一个单峰函数,那么我们就可以三分对角线了,对每个对角线的三分长度即可。
#include<bits/stdc++.h>
#define eps 1e-8
using namespace std;
double check(double y,double x,double n){
double p=(x+y+n)/2.0;
double tmp=p*(p-x)*(p-y)*(p-n);
double s=sqrt(tmp);
return s;
}
double sf(double a,double b,double c,double d){
double l=0.0;double r;
if(a+b>c+d+eps) r=c+d;
else r=a+b;
//printf("r=%.7f\n",r);
while(r-l>eps){
double len=(r-l)/3.0;
double ml=l+len;
double mr=r-len;
if(check(a,b,ml)+check(c,d,ml)-check(a,b,mr)-check(c,d,mr)>eps){
r=mr;
}
else l=ml;
//printf("len=%.7f\n",len);
//printf("ml=%.7f,mr=%.7f,l=%.7f,r=%.7f\n",ml,mr,l,r);
//printf("s1=%.7f,s2=%.7f\n",check(a,b,ml)+check(c,d,ml),check(a,b,mr)+check(c,d,mr));
}
//double res=check()
return check(a,b,l)+check(c,d,l);
}
int main(){
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
double ans=0.0;
double k=0.0;
//k=check(3.0,4.0,5.0);printf("k==%.7f\n",k);
ans=max(ans,sf(a,b,c,d));
ans=max(ans,sf(a,c,b,d));
ans=max(ans,sf(a,d,b,c));
printf("%.7f\n",ans);
return 0;
}
法二:
对于一个四条边长一定的四边形,当且仅当它是圆内接四边形时面积最大,对于圆内接四边形,有
Bretschneider公式(
)
,
#include<bits/stdc++.h>
using namespace std;
int main()
{
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
double p=(a+b+c+d)/2;
printf("%.15f\n",sqrt((p-a)*(p-b)*(p-c)*(p-d)));
return 0;
}