浙江中医药大学大学生程序设计竞赛problemC Wpremig的三角形(二分计算几何)
这题就太有说法了…像我这种萌新看完之后完全没思路,我能回炉从造吗
这是一道好题,看题解全程跪着看完的,防止忘了还是写个…
如果想面积最大,那么每两个三角形相交的位置和每边缘的三角形与边界相交的位置一样高,设这个高度为mid,mid下面是一个矩形,答案就是高度的三角形面积和加上这个矩形面积
对每个三角形,因为想高度最大所以最短边贴着底边的,有三角形面积公式
p=(a+b+c)/2;
area=sqrt(p(p-a)(p-b)(p-c))*
这个三角形的最大高度就是
h=area*2/h;
写一个求底边之和的函数f()
mid二分求,对于已mid为底边的三角形,底边之和f(mid)=l
求出mid后把每个部分的面积加起来就是答案了
三角形面积。。。?
底乘高除二啊(高中学的全忘了是这样没错了)!
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn=100010;
const double eps=1e-6;
double a[maxn],b[maxn],c[maxn],h[maxn],area[maxn];
int n;double len;int t;
double f(double k){
double ret=0;
for(int i=1;i<=n;i++){
if(k<h[i]){
ret+=a[i]*(1.0-k/h[i]);
}
}return ret;
}
int main(){
int i;
scanf("%d",&t);
while(t--){
scanf("%d%lf",&n,&len);
for(i=1;i<=n;i++){
scanf("%lf%lf%lf",&a[i],&b[i],&c[i]);
double p=(a[i]+b[i]+c[i])/2;
area[i]=sqrt(p*(p-a[i])*(p-b[i])*(p-c[i]));
h[i]=area[i]*2.0/a[i];
//cout<<h[i]<<endl;
}
double mid,l=0,r=100000;
while(fabs(r-l)>eps){
mid=(l+r)/2.0;
if(f(mid)<=len){
r=mid;
}else{
l=mid;
}
}double ans=0;
for(i=1;i<=n;i++){
if(mid<h[i]){
ans+=a[i]*(1.0-mid/h[i])*(h[i]-mid)/2.0;
}
}
ans+=mid*len;
printf("%.3f\n",ans);
}
}