正题
题目给出的坐标,要你求AB,CD上两个点
,使得
。
首先我们先固定点E,移动F。
1.F肯定存在一个唯一的最小点使得当前E的Ans最小。
2.其他的一定从这个点开始往两边单调上升。
这两个都可以很好的感性理解。
那么下凹函数三分就可以了。
那么我们又可以发现对于每一个E的Ans,他们也是组成了一个下凹函数。
三分内用三分算答案即可。注意这里的正负性,要用abs。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
struct node{
double x,y;
friend node operator+(const node a,const node b){return (node){a.x+b.x,a.y+b.y};}
friend node operator/(const node a,int x){return (node){a.x/x,a.y/x};}
friend node operator-(const node a,const node b){return (node){a.x-b.x,a.y-b.y};}
}a,b,c,d;
double qw,we,er;
double q=0.00001;
double dis1,dis2;
double get_dis(node x,node y){
return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}
double get_ans(node k){
node l=c,r=d;
double ans;
while(fabs(r.x-l.x)>q || fabs(r.y-l.y)>q){
node mid1=l+(r-l)/3,mid2=(mid1+r)/2;
double f1=get_dis(a,k)/qw+get_dis(k,mid1)/er+get_dis(mid1,d)/we,f2=get_dis(a,k)/qw+get_dis(k,mid2)/er+get_dis(mid2,d)/we;
if(f1>f2) l=mid1;
else r=mid2;
ans=min(f1,f2);
}
return ans;
}
int main(){
scanf("%lf %lf %lf %lf",&a.x,&a.y,&b.x,&b.y);
scanf("%lf %lf %lf %lf",&c.x,&c.y,&d.x,&d.y);
scanf("%lf %lf %lf",&qw,&we,&er);
dis1=get_dis(a,b);
dis2=get_dis(c,d);
node l=a,r=b;
double ans;
do{
node mid1=l+(r-l)/3,mid2=(mid1+r)/2;
double f1=get_ans(mid1),f2=get_ans(mid2);
if(f1>f2) l=mid1;
else r=mid2;
ans=min(f1,f2);
}while(fabs(r.x-l.x)>=q || fabs(r.y-l.y)>=q);
printf("%.2lf",ans);
}
782

被折叠的 条评论
为什么被折叠?



