标签:strong sqrt printf ++ point namespace lin print pac
我们假定在\(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\n", 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
标签:strong sqrt printf ++ point namespace lin print pac
原文地址:https://www.cnblogs.com/lifehappy/p/12929612.html