BZOJ1857 [Scoi2010]传送带(洛谷P2571)

版权声明:蒟蒻Blog随意转载 https://blog.csdn.net/a1799342217/article/details/81986884

三分

BZOJ题目传送门
洛谷题目传送门

对在AB上走的距离和在CD上走的距离进行三分,也就是三分套三分。画画图就会发现这两个都是单峰函数(当离开点逐渐远离A/C时,最终所花的时间先变少后变多)。

代码:

#include<cmath>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define eps 1e-3
using namespace std;
typedef double DB;
int ax,ay,bx,by,cx,cy,dx,dy,p,q,r;
#define sqr(x) ((x)*(x))
#define abs(x) ((x)>0?(x):-(x))
#define d(x1,y1,x2,y2) sqrt(sqr(x1-x2)+sqr(y1-y2)) 
inline DB pd(DB x,DB y){
    DB lx=cx,ly=cy,rx=dx,ry=dy,d1=d(ax,ay,x,y)/p;
    while (abs(rx-lx)>eps||abs(ry-ly)>eps){
        DB x1=lx+(rx-lx)/3,x2=lx+(rx-lx)/3*2;
        DB y1=ly+(ry-ly)/3,y2=ly+(ry-ly)/3*2;
        DB s1=d1+d(x,y,x1,y1)/r+d(x1,y1,dx,dy)/q;
        DB s2=d1+d(x,y,x2,y2)/r+d(x2,y2,dx,dy)/q;
        s1>s2?(lx=x1,ly=y1):(rx=x2,ry=y2);
    }
    return d1+d(x,y,lx,ly)/r+d(lx,ly,dx,dy)/q;
}
int main(){
    scanf("%d%d%d%d",&ax,&ay,&bx,&by);
    scanf("%d%d%d%d",&cx,&cy,&dx,&dy);
    scanf("%d%d%d",&p,&q,&r);
    DB lx=ax,ly=ay,rx=bx,ry=by;
    while (abs(rx-lx)>eps||abs(ry-ly)>eps){
        DB x1=lx+(rx-lx)/3,x2=lx+(rx-lx)/3*2;
        DB y1=ly+(ry-ly)/3,y2=ly+(ry-ly)/3*2;
        pd(x1,y1)>pd(x2,y2)?(lx=x1,ly=y1):(rx=x2,ry=y2);
    }
    return printf("%.2lf",pd(lx,ly)),0;
}

猜你喜欢

转载自blog.csdn.net/a1799342217/article/details/81986884