寄蒜几盒?

 

 1 struct Poi {
 2     LL x, y;
 3     Poi() {}
 4     Poi(LL X, LL Y)
 5         : x(X), y(Y) {}
 6     bool operator==(const Poi& R) const {
 7         return (x == R.x) && (y == R.y);
 8     }
 9     Poi operator+(const Poi& R) const {
10         return Poi(x + R.x, y + R.y);
11     }
12     Poi operator-(const Poi& R) const {
13         return Poi(x - R.x, y - R.y);
14     }
15     LL operator&(const Poi& R) const {
16         return x * R.x + y * R.y;
17     }
18     LL operator*(const Poi& R) const {
19         return x * R.y - y * R.x;
20     }
21     inline void read() {
22         ::read(x);
23         ::read(y);
24     }
25 };
26 struct Line {
27     Poi A, B;
28     Line() {}
29     Line(Poi a, Poi b)
30         : A(a), B(b) {}
31 };
32 inline LL dis2(Poi A, Poi B) {
33     return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
34 }
35 
36 inline bool ConvexCmp(const Poi& A, const Poi& B) {
37     if(A.x != B.x)
38         return A.x < B.x;
39     return A.y < B.y;
40 }
41 void GetConvex(Poi* a, int n, Poi* p, int& tot) {
42     std::sort(a, a + n, ConvexCmp);
43     p[0] = a[0];
44     tot = 1;
45     for(int i = 1; i < n; i++) {
46         while((tot > 1 && (p[tot - 1] - p[tot - 2]) * (a[i] - p[tot - 1]) <= 0)) {
47             --tot;
48         }
49         p[tot++] = a[i];
50     }
51     int temp = tot;
52     for(int i = n - 2; i >= 0; i--) {
53         while((tot > temp && (p[tot - 1] - p[tot - 2]) * (a[i] - p[tot - 1]) <= 0)) {
54             --tot;
55         }
56         p[tot++] = a[i];
57     }
58     --tot;
59     return;
60 }
总模板

 

如果要取实数绝对值,用fabs,c++98的abs不支持实数,返回的是整数。

------------------------------------------

直线用点 + 表示。

向量叉积:得到的是平行四边形的面积。不满足交换律。

1 × 2 = (x1y2 - x2y1)

p × q以p为基准,若q在逆时针方向,则叉积为正。

 

凸包:扫描。

 

大概就是先按照x排序,然后横着来回扫一遍,过去的时候得到下凸包,回来的时候得到上凸包。

 

如果叉积为负,就把当前的栈顶出栈。

模板题:洛谷P2742

 

 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 }
AC代码

 

线段相交:任一条线段延长都能把另一条线段的两端点分开。叉积正负性相反。

多边形面积:随便选一点,叉积。

点在半平面内:叉积。

点到直线距离:叉积。

点在多边形内:引多条射线/三角剖分。

直线夹角:点积。

直线交点

直线与凸多边形交点

凸包交

动态凸包:splay维护。

旋转卡壳

最小圆覆盖

随机化的应用

模拟退火的应用

离散化的应用

辛普森积分

点线对偶:凸包⇔半平面交。(a, b)  ->  y = ax - b

posted @ 2019-02-12 16:09  huyufeifei  阅读(83)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

ReadEra 阅读书籍

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜