[BZOJ 1857][SCOI2010]传送带
转载请注明出处:http://danihao123.is-programmer.com/
三分套三分入门题……
策略肯定是从A走到AB上一点,然后再走到CD上的一个点,再向D走。
很显然答案函数是一个关于那两个点下凸的东西(不会证?GeoGebra之类的东西画一下就好啦!还不如像我这样口胡),所以我们可以先对第一维三分,然后套上对第二维的三分……
代码:
/**************************************************************
Problem: 1857
User: danihao123
Language: C++
Result: Accepted
Time:244 ms
Memory:820 kb
****************************************************************/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <utility>
#include <cmath>
typedef double R;
const R eps = 1e-6;
int sign(R x) {
if(fabs(x) < eps) {
return 0;
} else {
if(x < 0) return -1;
else return 1;
}
}
struct Point {
R x, y;
Point(R qx = 0, R qy = 0) {
x = qx; y = qy;
}
};
typedef Point Vector;
Vector operator +(const Vector &a, const Vector &b) {
return Vector(a.x + b.x, a.y + b.y);
}
Vector operator -(const Point &a, const Point &b) {
return Vector(a.x - b.x, a.y - b.y);
}
Vector operator *(R x, const Vector &v) {
return Point(v.x * x, v.y * x);
}
Vector operator *(const Vector &v, R x) {
return Point(v.x * x, v.y * x);
}
R dot(const Vector &a, const Vector &b) {
return a.x * b.x + a.y * b.y;
}
R times(const Vector &a, const Vector &b) {
return a.x * b.y - a.y * b.x;
}
R dist(const Point &a, const Point &b) {
return sqrt(dot(a - b, a - b));
}
bool cmp(const Point &a, const Point &b) {
if(sign(a.x - b.x) == 0) {
return a.y < b.y;
} else {
return a.x < b.x;
}
}
Point A, B, C, D;
R p, q, r;
Vector D_AB, D_DC;
R f(const Point &AB, const Point &CD) {
return (dist(AB, A) / p + dist(CD, D) / q + dist(AB, CD) / r);
}
R F(Point AB) {
R L = 0, R = 1;
int T = 200;
while(T --) {
double M1 = L + (R - L) / 3;
double M2 = R - (R - L) / 3;
Point P1 = D + M1 * D_DC;
Point P2 = D + M2 * D_DC;
double f1 = f(AB, P1), f2 = f(AB, P2);
if(f1 < f2) {
R = M2;
} else {
L = M1;
}
}
return f(AB, D + L * D_DC);
}
R solve() {
R L = 0, R = 1;
int T = 200;
while(T --) {
double M1 = L + (R - L) / 3;
double M2 = R - (R - L) / 3;
Point P1 = A + M1 * D_AB;
Point P2 = A + M2 * D_AB;
double F1 = F(P1), F2 = F(P2);
if(F1 < F2) {
R = M2;
} else {
L = M1;
}
}
return F(A + L * D_AB);
}
int main() {
scanf("%lf%lf%lf%lf", &A.x, &A.y, &B.x, &B.y);
scanf("%lf%lf%lf%lf", &C.x, &C.y, &D.x, &D.y);
scanf("%lf%lf%lf", &p, &q, &r);
D_AB = B - A; D_DC = C - D;
printf("%.2lf\n", solve());
return 0;
}
评论 (0)