[Preface] I have not answered questions for a long time. The summer vacation is busy. O (Clerk □clerk) O
[Original question]
2458: [beijing2011] minimum triangle Time limit:10 sec Memory limit:128 MB
Submit:574 Solved:177
[Submit] [Status] Description
Xaviera has encountered an interesting problem.
There are N points on the plane, and xaviera wants to find the triangle with the smallest perimeter.
Xaviera wants to solve this problem because there are many points and the distribution is messy.
In order to reduce the difficulty of the problem, the triangle here also includes three points of collinearity.
Input
The first line contains an integer n indicating the number of points.
Each row in the next n Rows has two integers, indicating the coordinates of the point.
Output
The output contains only one row, containing a six-digit decimal number, which is the perimeter of the triangle with the shortest perimeter (rounding ).
Sample Input 4
1 1
2 3
3 3
3 4
Sample output3.414214
Hint
N ≤ 100% of the data.
Source
Day1
[Analysis] today, we have learned how to solve this kind of problem-divide governance. That's right, it's divide governance.
Let's talk about the nearest point of the plane where N is 10 ^ 5 (CF 245 Div 2 D ). It is easy to understand.
For details, refer to this blog.(In many cases, we only need to understand the principles of perceptual knowledge)The following describes the specific practices.
① The points on the plane are sorted by X coordinates (this is a permanent order ).
② Each recursion (L, R), the return value of the function is the closest point of all vertices between L and R.
③ If l = r, infinity is returned. If l + 1 = r, distance between two vertices is directly returned.
④ First recursion (L, mid) and (Mid + 1, R ). Obviously, the two return values may be set to D1 and D2. First, we set D = min (D1, D2), that is, the current optimal value is D.
⑤ Obviously, there is another situation. A point on the left and a point on the right have a relationship. Then, we can go from the mid position to the left to the mid-D, to the right to the Mid + D, then we can pull out all the vertices in this section-because only the vertices in these two sections may contribute less than D.
6. At this time, we need to be aware of the assurance of potential complexity (the actual principle is hard to understand ). First, if we want to enumerate the two vertices directly, we need n ^ 2. We first sort the extracted points by Y. (Nlogn) then it seems to be an enumeration of N ^ 2, but an optimization is added (start to enumerate I from the bottom, if y [J]-y [I]> D, it will directly break) -- this proves to be almost linear. Total complexity N * logn.
It is also similar to talking about this question. Because it is a triangle, we can change some details.
[Code]
# Include <cstdio> # include <cmath> # include <algorithm> # define n 200005 # define INF 210000000000.0 using namespace STD; struct arr {int X, Y ;} A [n], num [N]; int N, I, test; inline bool cmpx (const arr & A, const arr & B) {return. x <B. x;} inline bool cmpy (const arr & A, const arr & B) {return. Y <B. y;} inline double DIS (const arr & A, const arr & B) {return SQRT (. x-b.x) * 1. * (. x-b.x) +. y-b.y) * 1. * (. y-b.y);} inline double work (Int L, int R) {If (L = r) return INF; If (L + 1 = r) return INF; If (L + 2 = r) return DIS (A [L], a [L + 1]) + DIS (A [L + 1], a [R]) + DIS (A [L], A [R]); int mid = (L + r)> 1; double d1 = work (L, mid), D2 = work (Mid + 1, R ); double D = min (D1, D2), ANS = D, DD = D/2.0; int CNT = 0; For (INT I = L; I <= R; I ++) if (FABS (A [Mid]. x-A [I]. x) <= dd) num [++ CNT] = A [I]; sort (Num + 1, num + CNT + 1, cmpy); For (INT I = 1; I <cnt-1; I ++) for (Int J = I + 1; j <CNT; j ++) {If (Num [J]. y-n Um [I]. y> dd) break; For (int K = J + 1; k <= CNT; k ++) {If (Num [K]. y-num [I]. y> dd) break; double temp = DIS (Num [I], num [J]) + DIS (Num [I], num [k]) + DIS (Num [J], num [k]); If (temp <ans) ans = temp ;}return ans ;}int main () {read (N ); // read optimization will not be pasted. For (I = 1; I <= N; I ++) read (A [I]. x), read (A [I]. y); sort (a + 1, A + n + 1, cmpx); printf ("%. 6lf ", work (1, N); Return 0 ;}