HDU 4816 Bathysphere(數學)(2013 Asia Regional Changchun)

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   os   io   for   

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=4816

Problem DescriptionThe Bathysphere is a spherical deep-sea submersible which was unpowered and lowered into the ocean on a cable, and was used to conduct a series of dives under the sea. The Bathysphere was designed for studying undersea wildlife.

The Bathysphere was conducted from the deck of a ship. After counted, the ship should not move, so choosing the position where the Bathysphere was conducted is important.

A group of scientists want to study the secrets of undersea world along the equator, and they would like to use the Bathysphere. They want to choose the position where the Bathysphere can dive as deep as possible. Before conducting the Bathysphere, they have a map of the seabed, which tell them the shape of the seabed. They draw a line on the equator of the map to mark where they will release the Bathysphere, as a number axis. Suppose the axis is draw from 0 to L. But when they release the Bathysphere, they can‘t know where they are accurately, i.e., if they choose position x to release the Bathysphere, the real position will distribute between x-d and x+d with an equal probability, where d is given. The objective of the scientists is very simple, i.e., to maximize the expected depth.

For the ease of presentation, the shape of the seabed is described as a poly line. Given N points ) , ( Xi,Yi ) as the vertices, where Xi and Yi indicate the position and the depth of the i-th vertex, respectively, the ploy line is composed of the line segments that connect consecutive vertices. InputThe first line contains an integer T (1 ≤ T ≤ 25), the number of test cases.

Then T test cases follow. In each test case, the first line contains two integers N (2 ≤ N ≤ 2*10^5) and L (2 ≤ L ≤ 10^9), as described above. Then N lines follow, each line contains two integer Xi and Yi (1≤i≤N, 0≤ Yi ≤10^9), where point ( Xi,Yi ) is a vertex of the ploy line. It is assumed that X1 == 0 and Xn == L and Xi < Xi+1 for 1 ≤ i < N. Then the following line contains one integer d (0 ≤ d ≤ L/2), as described above. OutputFor each test case, choose a position between d and L-d, both inclusive, to conducted the Bathysphere, and calculate the expected depth. Output the expected depth in a line, rounded to 3 digits after the decimal point. ————————————————————————————————————————————————————————————————————————————————貼一下官方題解:

題目大意:
在海平面上找一點投放潛水艇,投放的準確地點存在誤差D,求最大的潛水深度期望。
題目分析:
即在海平面下再畫一條折線,然後用間距為2×D的豎線將圖截出,求截出的圖形的最大面積。
解法:
可以看出當將兩豎線不斷右移的過程中,除了一種狀態以外,其餘狀態對於面積的影響均為單調的。
此狀態為當左邊豎線所相交的折線為向上趨勢並且右邊豎線所相交的折線為向下趨勢並且在到達端點前,兩豎線與折線的交點的高度為相同的值時,此時面積最大。
所以,可以直接將兩豎線從左往右移動,每次移動一個端點的距離,如果出現該情況則計算中途可能出現的最大面積,否則記錄當前最大面積,即可於O(N)時間內得出結果。

————————————————————————————————————————————————————————————————————————————————

PS:我寫這題在HDU上不用long double就過不了。也完全不知道怎麼用double過了,有知道怎麼辦的請務必告訴我!三分就不要了……

 

代碼(2390MS):

 1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 typedef long double LDB; 8  9 const int MAXN = 200010;10 const LDB EPS = 1e-6;11 12 inline int sgn(LDB x) {13     return (x > EPS) - (x < -EPS);14 }15 16 int x[MAXN], y[MAXN];17 int n, d, L, T;18 19 struct Game {20     LDB a, b, c;21     Game() {}22     Game(LDB a, LDB b, LDB c): a(a), b(b), c(c) {}23     Game operator - (const Game &rhs) const {24         return Game(a - rhs.a, b - rhs.b, c - rhs.c);25     }26     LDB val_at(LDB x) {27         return a * x * x + b * x + c;28     }29     LDB max_val(LDB l, LDB r) {30         LDB res = max(val_at(l), val_at(r));31         if(sgn(a) < 0) {32             LDB t = - b / 2 / a;33             if(sgn(l - t) <= 0 && sgn(t - r) <= 0)34                 res = val_at(t);35         }36         return res;37     }38 };39 40 Game get(int pos, LDB v = 0.0) {41     LDB k = LDB(y[pos + 1] - y[pos]) / (x[pos + 1] - x[pos]);42     LDB t = y[pos] - k * x[pos];43     LDB a = k / 2, b = t, c = -((k / 2) * x[pos] + t) * x[pos];44     return Game(a, 2 * v * a + b, a * v * v + b * v + c);45 }46 47 LDB area(int pos) {48     return (y[pos] + y[pos + 1]) / 2.0 * (x[pos + 1] - x[pos]);49 }50 51 LDB solve() {52     if(d == 0) {53         int res = 0;54         for(int i = 1; i <= n; ++i) res = max(res, y[i]);55         return res;56     }57     LDB nowx = 0, res = 0, s = 0;58     int l = 1, r = 1;59     while(r < n && x[r + 1] <= d)60         s += area(r++);61     if(r == n) res = s;62     while(r < n) {63         LDB minx = min(x[l + 1] - nowx, x[r + 1] - nowx - d);64         res = max(res, s + (get(r, d) - get(l)).max_val(nowx, nowx + minx));65         nowx += minx;66         if(sgn(x[l + 1] - nowx) == 0) s -= area(l++), nowx = x[l];67         if(sgn(x[r + 1] - nowx - d) == 0) s += area(r++), nowx = x[r] - d;68     }69     return res / d;70 }71 72 int main() {73     scanf("%d", &T);74     while(T--) {75         scanf("%d%d", &n, &L);76         for(int i = 1; i <= n; ++i) scanf("%d%d", &x[i], &y[i]);77         x[n + 1] = x[n];78         scanf("%d", &d); d <<= 1;79         printf("%.3f\n", (double)solve());80     }81 }
View Code

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.