HDU 3400(Line belt 三分套娃)
Posted lifehappy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 3400(Line belt 三分套娃)相关的知识,希望对你有一定的参考价值。
Line belt
思路
我们假定在(A, B)上选取点(E),在(C, D)上选取点(F),我们的移动路径是(A -> E -> F -> D)。
当我们确定(E)点时,不难发现(dis(E -> F + F -> D))是一个凹函数,具有极小值。
当我们确定(F)点时不难发现(dis(A -> E + E -> F))也是一个凹函数,具有极小值。
这两段函数连接起来,不难发现也是一个凹函数,具有极小值。
这就好像是一个套娃的三分了,我们可以通过确定(E)点,然后去找到(min dis(E -> F + F -> D))
然后由于函数具有整体的凹性,我们只要通过基础的三分来三分点(E),就能确定最后的答案。
具体有一些细节在代码中。
代码
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
double P, Q, R;
struct point {
double x, y;
point(double a = 0.0, double b = 0.0) : x(a), y(b) {};
}A, B, C, D, E, F;
double dis(point a, point b) {
//这里我也是看了评论,不加eps就wa,
//好像如果不加eps会导致答案偏小。
return sqrt(eps + (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double calc2(double x) {
//通过长度和向量确定F点坐标,
//一定要注意坐标C, D的前后顺序,
F = point(C.x + (x / dis(C, D)) * (D.x - C.x), C.y + (x / dis(C, D)) * (D.y - C.y));
//cost(E -> F + F -> D)
return (dis(E, F) / R) + ((dis(C, D) - x) / Q);
}
double calc1(double x) {
//通过长度和向量来确定E点的坐标。
//一定要注意坐标A, B的前后顺序,
E = point(A.x + (x / dis(A, B)) * (B.x - A.x), A.y + (x / dis(A, B)) * (B.y - A.y));
double l = 0, r = dis(C, D);//从长度三分F点。
for(int i = 0; i < 100; i++) {
double lmid = l + (r - l) / 3;
double rmid = r - (r - l) / 3;
if(calc2(lmid) >= calc2(rmid)) l = lmid;
else r = rmid;
}
//calc2 + cost(A -> E)。
return calc2(l) + (x / P);
}
int main() {
// freopen("in.txt", "r", stdin);
int t; scanf("%d", &t);
while(t--) {
scanf("%lf %lf", &A.x, &A.y);
scanf("%lf %lf", &B.x, &B.y);
scanf("%lf %lf", &C.x, &C.y);
scanf("%lf %lf", &D.x, &D.y);
scanf("%lf %lf %lf", &P, &Q, &R);
double l = 0, r = dis(A, B);//从长度三分E点。
// cout << l << " " << r << endl;
for(int i = 0; i < 100; i++) {
double lmid = l + (r - l) / 3;
double rmid = r - (r - l) / 3;
if(calc1(lmid) >= calc1(rmid)) l = lmid;
else r = rmid;
}
// cout << l << " " << r << endl;
printf("%.2f
", calc1(l));
// puts("");
}
return 0;
}
一组样例及答案
8
0 0 4 1
4 1 0 2
8 8 1
0 0 0 100
100 0 100 100
2 2 1
8 0 23 8
4 2 91 0
4 9 10
0 0 2 2
0 2 2 0
4 3 1
1 8 1000 10
0 689 10 1000
90 1 20
4 9 4 20
4 41 4 60
4 4 1
4 9 4 20
4 91 4 60
4 3 1
0 5 8 5
2 5 4 0
6 9 3
1.03
136.60
8.30
0.83
49.60
28.50
42.75
0.93
以上是关于HDU 3400(Line belt 三分套娃)的主要内容,如果未能解决你的问题,请参考以下文章