[BZOJ 1857][SCOI 2010]传送带(三分套三分)

来源:互联网 发布:智能家居 知乎 编辑:程序博客网 时间:2024/06/05 21:07

题目链接

http://www.lydsy.com/JudgeOnline/problem.php?id=1857

思路

三分套三分,首先三分在传送带AB上的运动时间,然后在确定了在AB上的运动时间后,三分在CD上的运动时间。
如果此题没有单峰函数的特征,我想也只能用退火套退火乱搞了。。。
当然我刚开始比较naive,真的就去三分运动时间了,这样做比较麻烦,后来翻了下hzwer的题解发现了一个很不错的做法:不三分运动时间,而是三分离开这条传送带时的坐标,这样做就简单多了。

代码

蒟蒻太傻逼,刚开始弄成了求最大值,一直调不出来,然后三分还有几个地方写挂了QAQ

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#include <cmath>#define EPS 1e-4using namespace std;double P,Q,R,ax,ay,bx,by,cx,cy,dx,dy;inline double dist(double x1,double y1,double x2,double y2){    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}inline double calc(double sx,double sy) //在(sx,sy)处离开了传送带AB{    double lowerBoundx=cx,upperBoundx=dx;    double lowerBoundy=cy,upperBoundy=dy;    while(fabs(upperBoundx-lowerBoundx)>EPS||fabs(upperBoundy-lowerBoundy)>EPS)    {        double midx1=lowerBoundx+(upperBoundx-lowerBoundx)/3,midx2=upperBoundx-(upperBoundx-lowerBoundx)/3;        double midy1=lowerBoundy+(upperBoundy-lowerBoundy)/3,midy2=upperBoundy-(upperBoundy-lowerBoundy)/3;        double f1=dist(ax,ay,sx,sy)/P+dist(sx,sy,midx1,midy1)/R+dist(midx1,midy1,dx,dy)/Q;        double f2=dist(ax,ay,sx,sy)/P+dist(sx,sy,midx2,midy2)/R+dist(midx2,midy2,dx,dy)/Q;        if(f1<f2) upperBoundx=midx2,upperBoundy=midy2; //!!!!!        else lowerBoundx=midx1,lowerBoundy=midy1; //!!!!!    }    return dist(ax,ay,sx,sy)/P+dist(sx,sy,lowerBoundx,lowerBoundy)/R+dist(lowerBoundx,lowerBoundy,dx,dy)/Q;}int main(){    scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy,&P,&Q,&R);    double lowerBoundx=ax,upperBoundx=bx;    double lowerBoundy=ay,upperBoundy=by;    while(fabs(upperBoundx-lowerBoundx)>EPS||fabs(upperBoundy-lowerBoundy)>EPS)    {        double midx1=lowerBoundx+(upperBoundx-lowerBoundx)/3,midx2=upperBoundx-(upperBoundx-lowerBoundx)/3;        double midy1=lowerBoundy+(upperBoundy-lowerBoundy)/3,midy2=upperBoundy-(upperBoundy-lowerBoundy)/3;        double f1=calc(midx1,midy1),f2=calc(midx2,midy2);        if(f1<f2) upperBoundx=midx2,upperBoundy=midy2; //!!!!!        else lowerBoundx=midx1,lowerBoundy=midy1; //!!!!!    }    printf("%.2lf",calc(lowerBoundx,lowerBoundy));    return 0;}
0 0