当前位置: 代码迷 >> 综合 >> bzoj1857 传送带
  详细解决方案

bzoj1857 传送带

热度:69   发布时间:2024-01-09 11:53:08.0
传送带

题目背景:

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;
}