bzoj1857 传送带

传送带

题目背景:

bzoj1857

分析:表示自己一开始还真的没有想到三分答案,但是思考一下好像很显然,我们可以比较清楚的知道,最优的情况肯定是先从A出发沿AB走一段距离(可以为零),然后再走到CD上某一位置,然后到达D点,而在最优位置的两侧都是没有那么优的,也就是满足单峰性质,所以我们可以三分了,我们利用三分套三分,先分AB上的位置,并针对这个位置,三分在CD上的这个位置的最优终点,然后这个题就比较清晰了(重载一下点的加减写起来会很方便)

Source

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#include <cmath>
#include <cctype>
 
using namespace std;
 
const double eps = 1e-8;
 
struct Point
{
    double x, y;
    Point(double x, double y) : x(x), y(y) {}
    Point()  {}
    friend Point operator + (const Point &a, const Point &b) { return Point(a.x + b.x, a.y + b.y); }
    friend Point operator - (const Point &a, const Point &b) { return Point(a.x - b.x, a.y - b.y); }
    friend Point operator * (const Point &a, const double &b) { return Point(a.x * b, a.y * b); }
    friend Point operator / (const Point &a, const double &b) { return Point(a.x / b, a.y / b); }
    friend double dis(const Point &a, const Point &b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); }
}A, B, C, D;
double v1, v2, v0;
 
double find(Point F, Point S, Point T)
{
    Point l = S, r = T;
    double x;
    while(dis(l, r) > eps)
    {
        Point mid1 = l + (r - l) / 3.0, mid2 = r - (r - l) / 3.0;
        double t1 = dis(mid1, T) / v2 + dis(F, mid1) / v0;
        double t2 = dis(mid2, T) / v2 + dis(F, mid2) / v0;
        if(t1 < t2) r = mid2;
        else l = mid1; 
    }
    return dis(F, l) / v0 + dis(l, T) / v2;
}
 
int main()
{
    cin >> A.x >> A.y >> B.x >> B.y;
    cin >> C.x >> C.y >> D.x >> D.y;
    cin >> v1 >> v2 >> v0;
    Point l = A, r = B;
    while(dis(l, r) > eps)
    {
        Point mid1 = l + (r - l) / 3.0, mid2 = r - (r - l) / 3.0;
        double t1 = dis(A, mid1) / v1 + find(mid1, C, D);
        double t2 = dis(A, mid2) / v2 + find(mid2, C, D);
        if(t1 < t2) r = mid2;
        else l = mid1;
    }
    double t = dis(A, l) / v1 + find(l, C, D);
    printf("%.2f", t);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值