若是要取實數絕對值,用fabs,c++98的abs不支持實數,返回的是整數。c++
------------------------------------------ide
直線用點 + 點表示。spa
向量叉積:獲得的是平行四邊形的面積。不知足交換律。code
1 × 2 = (x1y2 - x2y1)blog
p × q以p爲基準,若q在逆時針方向,則叉積爲正。排序
凸包:掃描。get
大概就是先按照x排序,而後橫着來回掃一遍,過去的時候獲得下凸包,回來的時候獲得上凸包。it
若是叉積爲負,就把當前的棧頂出棧。io
模板題:洛谷P2742event
1 /** 2 * by huyufeifei 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cmath> 7 8 const int N = 100010; 9 const double eps = 1e-8; 10 11 struct Vec { 12 double x, y; 13 Vec(double X = 0, double Y = 0) { 14 x = X; 15 y = Y; 16 } 17 inline double operator *(const Vec &w) const { 18 return x * w.y - w.x * y; 19 } 20 inline double operator &(const Vec &w) const { 21 return x * w.x + y * w.y; 22 } 23 inline Vec operator -(const Vec &w) const { 24 return Vec(x - w.x, y - w.y); 25 } 26 inline bool operator <(const Vec &w) const { 27 if(fabs(x - w.x) > eps) { 28 return x < w.x; 29 } 30 return y < w.y; 31 } 32 }; 33 typedef Vec Poi; 34 35 inline double Len(Vec a) { 36 return sqrt(a & a); 37 } 38 39 inline int getConvex(int n, Poi *a, Poi *p) { 40 std::sort(a + 1, a + n + 1); 41 int top = 1; 42 p[1] = a[1]; 43 for(int i = 2; i <= n; i++) { 44 while(top > 1 && (p[top] - p[top - 1]) * (a[i] - p[top]) <= 0) { 45 top--; 46 } 47 p[++top] = a[i]; 48 } 49 int t = top; 50 for(int i = n - 1; i >= 1; i--) { 51 while(top > t && (p[top] - p[top - 1]) * (a[i] - p[top]) <= 0) { 52 top--; 53 } 54 p[++top] = a[i]; 55 } 56 top--; 57 return top; 58 } 59 60 Poi a[N], b[N]; 61 62 int main() { 63 64 int n; 65 scanf("%d", &n); 66 for(int i = 1; i <= n; i++) { 67 scanf("%lf%lf", &a[i].x, &a[i].y); 68 } 69 int t = getConvex(n, a, b); 70 double ans = 0; 71 for(int i = 2; i <= t; i++) { 72 ans += Len(b[i] - b[i - 1]); 73 } 74 ans += Len(b[1] - b[t]); 75 printf("%.2f\n", ans); 76 77 return 0; 78 }
線段相交:任一條線段延長都能把另外一條線段的兩端點分開。叉積正負性相反。
多邊形面積:隨便選一點,叉積。
點在半平面內:叉積。
點到直線距離:叉積。
點在多邊形內:引多條射線/三角剖分。
直線夾角:點積。
直線交點:
直線與凸多邊形交點:
凸包交:
動態凸包:splay維護。
旋轉卡殼:
最小圓覆蓋:
隨機化的應用:
模擬退火的應用:
離散化的應用:
辛普森積分:
點線對偶:凸包⇔半平面交。(a, b) -> y = ax - b