[SCOI2010]傳送帶
阿新 • • 發佈:2018-11-11
首先令E點表示在E點離開傳送帶AB,F點表示在F點上傳送帶CD,則總用時為:dis(A, E) / p + dis(E, F) / r + dis(F, D) / q。然而這是一個有兩個變數的函式。於是有一個不錯的方法:把E成引數,然後就變成了一個形如f(x) = √(t2 + x2) - x的函式,雖然我證不出來是一個單峰函式,但是幾何畫板告訴我是。於是我們可以三分求F。至於E,再三分求。
所以說,這是一道二維的三分套三分的題,三分求E,假設E已知的情況下三分求F。
程式碼很好懂。
1 #include<cstdio> 2View Code#include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14#define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 //const int maxn = ; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ' '; 25 while(!isdigit(ch)) {last = ch; ch = getchar();}26 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 27 if(last == '-') ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar('-'); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + '0'); 35 } 36 37 int ax, ay, bx, by, cx, cy, dx, dy; 38 int p, q, r; 39 40 db dis(db lx, db ly, db rx, db ry) 41 { 42 return sqrt((rx - lx) * (rx - lx) + (ry - ly) * (ry - ly)); 43 } 44 45 db calcF(db Ex, db Ey) 46 { 47 db Lx = cx, Ly = cy, Rx = dx, Ry = dy; 48 while(dis(Lx, Ly, Rx, Ry) > eps) 49 { 50 db Dx = (Rx - Lx) / 3.00, Dy = (Ry - Ly) / 3.00; 51 db m1x = Lx + Dx, m2x = Rx - Dx; 52 db m1y = Ly + Dy, m2y = Ry - Dy; 53 db ans1 = dis(Ex, Ey, m1x, m1y) / r + dis(m1x, m1y, dx, dy) / q; 54 db ans2 = dis(Ex, Ey, m2x, m2y) / r + dis(m2x, m2y, dx, dy) / q; 55 if(ans1 < ans2 + eps) Rx = m2x, Ry = m2y; 56 else Lx = m1x, Ly = m1y; 57 } 58 return dis(Ex, Ey, Lx, Ly) / r + dis(Lx, Ly, dx, dy) / q; 59 } 60 db calcE() 61 { 62 db Lx = ax, Ly = ay, Rx = bx, Ry = by; 63 while(dis(Lx, Ly, Rx, Ry) > eps) 64 { 65 db Dx = (Rx - Lx) / 3.00, Dy = (Ry - Ly) / 3.00; 66 db m1x = Lx + Dx, m2x = Rx - Dx; 67 db m1y = Ly + Dy, m2y = Ry - Dy; 68 db ans1 = calcF(m1x, m1y) + dis(ax, ay, m1x, m1y) / p; 69 db ans2 = calcF(m2x, m2y) + dis(ax, ay, m2x, m2y) / p; 70 if(ans1 < ans2 + eps) Rx = m2x, Ry = m2y; 71 else Lx = m1x, Ly = m1y; 72 } 73 return calcF(Lx, Ly) + dis(ax, ay, Lx, Ly) / p; 74 } 75 76 int main() 77 { 78 ax = read(), ay = read(); bx = read(), by = read(); 79 cx = read(), cy = read(), dx = read(), dy = read(); 80 p = read(), q = read(), r = read(); 81 printf("%.2lf\n", calcE()); 82 return 0; 83 }