【BZOJ1857】三分套三分

来源:互联网 发布:windows assembly 编辑:程序博客网 时间:2024/04/28 10:11

看了这位dalao的题解之后写的。

三分他离开线段AB和CD的位置。设他在E点离开线段AB最优,可以想象在E点两边离开都不如在E点离开优,所以它是一个单峰的函数,可以用三分求最小值(对这里时间最短是最小值)。我们在查找每一个可能的E点的时候在CD上三分一个F点。因为这道题嗯数据很小,所以复杂度高也是可以接受的。

#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>using namespace std;const double EPS = 1e-4;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 check(double x, double y){    double lx = cx, ly = cy, rx = dx, ry = dy;    while (fabs(lx - rx) > EPS || fabs(ly - ry) > EPS)    {        double mx1 = lx + (rx - lx) / 3, my1 = ly + (ry - ly) / 3;        double mx2 = rx - (rx - lx) / 3, my2 = ry - (ry - ly) / 3;        double f1 = dist(ax, ay, x, y) / P + dist(x, y, mx1, my1) / R + dist(mx1, my1, dx, dy) / Q;        double f2 = dist(ax, ay, x, y) / P + dist(x, y, mx2, my2) / R + dist(mx2, my2, dx, dy) / Q;        if (f1 < f2) rx = mx2, ry = my2;        else lx = mx1, ly = my1;    }    return dist(ax, ay, x, y) / P + dist(x, y, lx, ly) / R + dist(lx, ly, dx, dy) / Q;}int main(){    scanf("%lf %lf %lf %lf", &ax, &ay, &bx, &by);    scanf("%lf %lf %lf %lf", &cx, &cy, &dx, &dy);    scanf("%lf %lf %lf", &P, &Q, &R);    double lx = ax, ly = ay, rx = bx, ry = by;    while (fabs(lx - rx) > EPS || fabs(ly - ry) > EPS)    {        double mx1 = lx + (rx - lx) / 3, my1 = ly + (ry - ly) / 3;        double mx2 = rx - (rx - lx) / 3, my2 = ry - (ry - ly) / 3;        double f1 = check(mx1, my1);        double f2 = check(mx2, my2);        if (f1 < f2) rx = mx2, ry = my2;        else lx = mx1, ly = my1;    }    printf("%.2lf\n", check(lx, ly));    return 0;}

但是我写完之后T了,慢了一倍。
最开始我是用一个结构体存的坐标,我就想结构体是不是会慢,我就又写了一遍把它换成了两个double,还是T。

呃最后发现是我求m1和m2的时候我fabs(lx - rx)。。。算了很多次就T了。。。。

这个题一开始看到之后完全不会做,但是实际上不难,也很好想,单峰好像也很显然,我太弱了quq

0 0
原创粉丝点击