bzoj1857

1857: [Scoi2010]传送带

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 1487  Solved: 814
[Submit][Status][Discuss]

Description

在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间

Input

输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 第三行是3个整数,分别是P,Q,R

Output

输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留到小数点后2位

Sample Input

0 0 0 100

100 0 100 100

2 2 1

Sample Output

136.60

HINT

对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10

Source

Day2

从黄学长那里抄了个三分

三分是一个乱搞利器,因为即使一个函数不是单峰的,三分也可以找到一个较优的解,实在不行还有退火套退火。。。

这道题三分两次,先三分第一条传送带上走多远,在第一个基础上再三分第二个传送带上走多远

#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-3;
struct position {
    int x, y;
} A, B, C, D;
int p, q, r;
inline double dis(double x1, double y1, double x2, double y2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); }
inline double cal(double x, double y)
{
    double lx = C.x, ly = C.y, rx = D.x, ry = D.y;
    double x1, x2, y1, y2, t1, t2;
    while(fabs(rx - lx) > eps || fabs(ry - ly) > eps)
    {
        x1 = lx + (rx - lx) / 3; y1 = ly + (ry - ly) / 3;
        x2 = lx + (rx - lx) / 3 * 2; y2 = ly + (ry - ly) / 3 * 2;
        t1 = dis(x, y, A.x, A.y) / p + dis(x, y, x1, y1) / r + dis(x1, y1, D.x, D.y) / q;
        t2 = dis(x, y, A.x, A.y) / p + dis(x, y, x2, y2) / r + dis(x2, y2, D.x, D.y) / q;
        if(t1 > t2) lx = x1, ly = y1; else rx = x2, ry = y2;
    }
    return dis(x, y, A.x, A.y) / p + dis(lx, ly, x, y) / r + dis(lx, ly, D.x, D.y) / q;
}
int main()
{
    scanf("%d%d%d%d", &A.x, &A.y, &B.x, &B.y);
    scanf("%d%d%d%d", &C.x, &C.y, &D.x, &D.y);
    scanf("%d%d%d", &p, &q, &r);
    double lx = A.x, ly = A.y, rx = B.x, ry = B.y;
    double x1, x2, y1, y2, t1, t2;
    while(fabs(rx - lx) > eps || fabs(ry - ly) > eps)
    {
        x1 = lx + (rx - lx) / 3; y1 = ly + (ry - ly) / 3;
        x2 = lx + (rx - lx) / 3 * 2; y2 = ly + (ry - ly) / 3 * 2;
        t1 = cal(x1, y1); t2 = cal(x2, y2);
        if(t1 > t2) lx = x1, ly = y1;
        else rx = x2, ry = y2;
    }
    printf("%.2lf\n", cal(lx, ly));
    return 0;
}
时间: 2024-12-17 02:07:45

bzoj1857的相关文章

bzoj1857 [ SCOI2010 ] -- 三分套三分

显然我们一定是先走到AB上一点X,然后走到CD上一点Y,最后到D. 那么答案就是|AX|/P+|XY|/R+|YD|/Q 假设我们已经确定了X,那么目标就是在CD上找一点Y,使|XY|/R+|YD|/Q最小. 显然这是个单峰函数. 那么三分套三分就可以了. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> us

bzoj1857: [Scoi2010]传送带

Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R.现在lxhgww想从A点走到D点,他想知道最少需要走多长时间 Input 输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 第三行是3个整数,分别是P,Q,R Output 输出数据为一行,表示lxhgww

【bzoj1857】传送带——三分套三分

我的第一道三分题目. 早上跟着cyc学了一下三分,晚上想练一下手发现没什么水题就找到了这一道2333 主要是证明是一个单峰函数,这也是本题最难的部分(网上好多人写出来但不会证明:)) 证明过程来自yyl dalao: 本题要讨论必使r<max(q,p),否则还要走什么传送带... 从A点出发,要使解最优,必定要走A->E->F->D,其中E是AB上一点,F为CD上一点. 因为E和F都是不确定的,我们不妨假设E点已经确定,那么CD上必定存在一点F使得EF和FD最优(先不考虑AE),那

【BZOJ-1857】传送带 三分套三分

1857: [Scoi2010]传送带 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 1077  Solved: 575[Submit][Status][Discuss] Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R.现在lxhgww想从A点走到D点,他想知道最少需要走多长时间 Input 输入

BZOJ1857:[Scoi2010]传送带——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=1857 Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R.现在lxhgww想从A点走到D点,他想知道最少需要走多长时间 Input 输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

[转载]hzwer的bzoj题单

counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ1202 BZOJ1051 BZOJ1001 BZOJ1588 BZOJ1208 BZOJ1491 BZOJ1084 BZOJ1295 BZOJ3109 BZOJ1085 BZOJ1041 BZOJ1087 BZOJ3038 BZOJ1821 BZOJ1076 BZOJ2321 BZOJ1934 BZOJ