Question: give some vectors to find the area of the surrounding polygon core.
I have nothing to say about it, that is, the template Question of the semi-plane interaction. I heard that this is a special question for his paper, but the data has been changed by POJ, and the time limit is very wide, n ^ 2 random water, and my nlgn is more time consuming than n ^ 2.
I will introduce the nlgn algorithm first. I will also introduce it in detail in my essay.
Step 1. Sort all the Half Planes by the polar angles. If the polar angles are the same, choose to retain one. O (nlogn)
Step2. use a deque queue to add the first two half planes.
Step 3: consider a new half plane each time:
A. the intersection of the two half planes at the top of the while deque is located outside the current half plane: Delete the half plane at the top of the deque.
B. the intersection of the two half planes at the bottom of while deque is located outside the current half plane: Delete the half plane at the bottom of deque.
C. Add the new half plane to the top of deque
Step 4. Delete unnecessary Half Planes at both ends.
The specific method is:
A. the intersection of the two half planes at the top of the while deque is located outside the half plane at the bottom: Delete the half plane at the top of the deque.
B. the intersection of the two half planes at the bottom of while deque is located outside the top half plane: Delete the half plane at the bottom of deque.
Repeat a and B until they cannot be deleted.
Step 5: Calculate the intersection between the top and bottom of deque.
I tried the accuracy one by one... Eventually 1e-10
[Cpp]
# Include <iostream>
# Include <fstream>
# Include <iomanip>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <cstdlib>
# Include <cmath>
# Include <set>
# Include <map>
# Include <queue>
# Include <stack>
# Include <string>
# Include <vector>
# Include <sstream>
# Include <cassert>
# Define LL long
# Define eps 1e-10
# Define inf 10000
# Define zero (a) fabs (a) <eps
# Define N 20005
Using namespace std;
Struct Point {
Double x, y;
} P [N * 2];
Struct Segment {
Point s, e;
Double angle;
Void get_angle () {angle = atan2 (e. y-s.y, e. x-s.x );}
} Seg [N];
Int m;
// If the cross product is positive, p2 is on the left side of the p0-p1
Double xmul (Point p0, Point p1, Point p2 ){
Return (p1.x-Snapshot X) * (p2.y-Snapshot y)-(p2.x-Snapshot X) * (p1.y-Snapshot y );
}
Point Get_Intersect (Segment s1, Segment s2 ){
Double u = xmul (s1.s, s1.e, s2.s), v = xmul (s1.e, s1.s, s2.e );
Point t;
T. x = (s2.s. x * v + s2.e. x * u)/(u + v); t. y = (s2.s. y * v + s2.e. y * u)/(u + v );
Return t;
}
Bool cmp (Segment s1, Segment s2 ){
// Sort by polar angle first
If (s1.angle> s2.angle) return true;
// Equal polar angles, front of the inner
Else if (zero (s1.angle-s2.angle) & xmul (s2.s, s2.e, s1.e)>-eps) return true;
Return false;
}
Void HalfPlaneIntersect (Segment seg [], int n ){
Sort (seg, seg + n, cmp );
Int tmp = 1;
For (int I = 1; I <n; I ++)
If (! Zero (seg [I]. angle-seg [tmp-1]. angle ))
Seg [tmp ++] = seg [I];
N = tmp;
Segment deq [N];
Deq [0] = seg [0]; deq [1] = seg [1];
Int head = 0, tail = 1;
For (int I = 2; I <n; I ++ ){
While (head <tail & xmul (seg [I]. s, seg [I]. e, Get_Intersect (deq [tail], deq [tail-1]) <-eps) tail --;
While (head <tail & xmul (seg [I]. s, seg [I]. e, Get_Intersect (deq [head], deq [head + 1]) <-eps) head ++;
Deq [++ tail] = seg [I];
}
While (head <tail & xmul (deq [head]. s, deq [head]. e, Get_Intersect (deq [tail], deq [tail-1]) <-eps) tail --;
While (head <tail & xmul (deq [tail]. s, deq [tail]. e, Get_Intersect (deq [head], deq [head + 1]) <-eps) head ++;
If (head = tail) return;
M = 0;
For (int I = head; I <tail; I ++)
P [m ++] = Get_Intersect (deq [I], deq [I + 1]);
If (tail> head + 1)
P [m ++] = Get_Intersect (deq [head], deq [tail]);
}
Double Get_area (Point p [], int & n ){
Double area = 0;
For (int I = 1; I <n-1; I ++)
Area + = xmul (p [0], p [I], p [I + 1]);
Return fabs (area)/2.0;
}
Int main (){
Int n;
While (scanf ("% d", & n )! = EOF ){
Seg [0]. s. x = 0; seg [0]. s. y = 0; seg [0]. e. x = 10000; seg [0]. e. y = 0; seg [0]. get_angle ();
Seg [1]. s. x = 10000; seg [1]. s. y = 0; seg [1]. e. x = 10000; seg [1]. e. y = 10000; seg [1]. get_angle ();
Seg [2]. s. x = 10000; seg [2]. s. y = 10000; seg [2]. e. x = 0; seg [2]. e. y = 10000; seg [2]. get_angle ();
Seg [3]. s. x = 0; seg [3]. s. y = 10000; seg [3]. e. x = 0; seg [3]. e. y = 0; seg [3]. get_angle ();
For (int I = 0; I <n; I ++ ){
Scanf ("% lf", & seg [I + 4]. s. x, & seg [I + 4]. s. y, & seg [I + 4]. e. x, & seg [I + 4]. e. y );
Seg [I + 4]. get_angle ();
}
HalfPlaneIntersect (seg, n + 4 );
Printf ("%. 1f \ n", Get_area (p, m ));
}
Return 0;
}