级边凸包构造法(extreme edge)

级边构造法的思想方法

  • 我们每次选举两个点,也就是一条边,然后对剩下的点做(ToLeftTest)如果这些点都在这条边的左边或者右边,我们可以认定这是一条级边。

我们可以分析出,这个算法的时间复杂度是 (O(n^3)) 的,明显优于之前的 (extreme point) 的算法。

代码如下

//Powered by CK
//级边凸包构造
#include<bits/stdc++.h>
using namespace std;
const double INF = 1e100;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int N = 1e5 + 10;
int n, cnt;
bool extreme[N];
struct point {
    double x, y;
    point(double a = 0.0, double b = 0.0) : x(a), y(b) {}
}p[N], ans[N];
int sgn(double x) {
    if(fabs(x) < eps)   return 0;
    if(x > 0)   return 1;
    return -1;
}
point operator - (point a, point b) {
    return point(a.x - b.x, a.y - b.y);
}
double dis(point a, point b) {
    point temp = a - b;
    return sqrt(temp.x * temp.x + temp.y * temp.y);
}
double cross(point a, point b) {
    return a.x * b.y - a.y * b.x;
}
bool cmp(point a,point b) {
    int flag = sgn(cross(a - ans[0], b - ans[0]));
    if(flag == 1)   return true;
    if(flag == 0 && dis(ans[0], a) < dis(ans[0], b))    return true;
    return false;
}
void extreme_edge() {
    memset(extreme, false, sizeof extreme);
    for(int i = 0; i < n; i++)
        for(int j = i + 1; j < n; j++) {
            bool emptyleft = true, emptyright = true;
            for(int k = 0;  k < n; k++) {
                if(k == i || k == j)    continue;
                int flag = sgn(cross(p[j] - p[i], p[k] - p[i]));
                if(flag == 1)   emptyleft = false;
                if(flag == -1)  emptyright = false;
            }
            if(emptyleft || emptyright) extreme[i] = extreme[j] = true;
        }
    for(int i = 0; i < n; i++)
        if(extreme[i])
            ans[cnt++] = p[i];
    ans[cnt] = ans[0];
    sort(ans + 1, ans + cnt, cmp);
    double target = 0;
    for(int i = 0; i < cnt; i++)
        target += dis(ans[i], ans[i + 1]);
    printf("%.2f
", target);
}
int main() {
    // freopen("in.txt", "r", stdin);
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
        scanf("%lf %lf", &p[i].x, &p[i].y);
    extreme_edge();
    return 0;
}

一组测试数据供检测算法正确性

同样求的的还是凸包的周长

73277.90
170
-8226.75 9172.55
-591.55 4936.73
9919.31 7621.54
-4789.82 -90.09
9062.45 -5989.51
9797.98 -4100.13
3832.62 -8465.63
-1456.86 5981.95
-2118.17 -8618.54
-813.65 4717.20
-5377.16 1286.52
5688.17 -5156.99
4221.92 339.41
-1645.44 194.35
6841.66 40.45
-9796.55 4884.59
-7866.19 -8398.81
9582.46 -1264.16
-5018.75 -497.22
-968.48 8962.84
7489.99 1294.98
-9595.26 -1905.48
7228.20 -6342.35
-3762.82 8161.95
1724.37 4703.80
-2638.17 -8880.97
9206.46 -7470.74
6771.48 5535.61
-4408.81 -9974.14
9745.85 -489.77
7734.30 -4073.78
207.60 -136.57
2911.95 -7881.95
-6649.46 7561.60
-5430.82 7193.05
-5499.17 -605.61
-5682.64 6250.36
4232.22 -4086.28
-9836.22 6955.57
-263.52 -4397.71
1013.26 1845.30
-7558.30 -4689.29
7408.86 6878.36
1876.85 -3066.84
-1482.42 -3757.60
5788.23 340.63
-4615.76 3409.22
6512.12 2555.71
-9585.73 8439.58
-6414.58 3187.95
3118.72 -8467.44
2615.34 -3891.22
-7894.79 -7157.41
-9601.78 7386.98
3325.03 -1480.12
6285.34 -541.25
-5442.80 -6978.48
-201.18 1568.29
-3838.25 -2329.84
4499.64 6440.00
8057.87 -4547.85
-1891.40 -6788.82
-7023.73 2077.35
-1133.54 -3387.65
5952.58 3276.44
-1843.94 2394.09
60.71 -1636.22
9371.57 9008.48
8411.43 -9962.06
-6973.24 -4461.95
2393.86 438.61
-1869.68 -4119.64
6166.15 -6552.74
-197.72 -831.90
7400.13 3247.23
-6863.51 -3543.26
4268.06 9124.47
3324.13 -6348.23
8693.45 -3479.25
-7985.71 -9313.48
5833.96 4345.56
-63.33 6957.47
9829.28 -1477.58
5764.26 -7006.78
-4207.84 -8200.12
1236.12 8399.94
8054.46 9803.03
2518.24 6021.43
4646.31 3338.57
-2175.58 2389.72
-1943.78 6949.42
-8715.73 -5613.77
-7790.58 3718.97
3058.20 2188.53
-4282.92 -3671.17
5703.56 -1568.38
-8635.25 4361.13
-3205.27 3654.77
1857.78 7850.43
7791.41 7969.98
-8190.22 -2905.83
9149.84 -1006.09
5989.25 8703.68
-8306.84 -3967.51
3808.12 7908.75
4237.83 -9493.05
-9934.48 -2886.20
7439.10 -7367.43
1941.46 -9297.47
3930.49 4348.84
-7765.31 -3907.77
4678.45 -1501.67
8858.52 1038.57
-8396.04 4263.95
-9419.19 7187.02
-3553.73 -1165.02
-979.06 9885.78
-4114.32 5350.47
6883.88 4228.30
2905.38 -2932.68
2459.30 -2627.63
-5590.64 7801.87
-9639.25 7083.72
-4904.64 8595.10
8521.96 6541.26
-2437.10 -9341.66
1426.08 -4598.15
-1313.60 -5460.46
9619.09 -2907.44
-7766.69 5561.20
-4568.76 2373.66
-2272.67 -4504.30
4983.53 -862.03
5568.69 -9504.63
6419.29 8469.95
-1603.52 5278.96
4408.78 6946.22
8715.10 3547.80
-9124.10 -4804.25
-7249.33 4678.44
-7993.08 -7301.47
575.58 -3353.11
-8522.70 -1154.17
2473.10 -4792.57
9958.54 238.04
-8444.98 9325.95
843.17 4248.05
2630.35 -7148.13
2256.68 -1183.78
7317.13 2459.62
5282.64 -1486.13
5415.26 1816.71
-1536.22 -3157.64
-7477.61 -7977.69
8544.21 4791.74
3900.90 8284.43
-2542.39 -4359.05
-5409.07 2841.65
-4427.36 -3985.43
-4214.52 -5845.58
-8817.80 3190.17
7442.54 2332.91
-3749.04 8651.16
7151.33 -9193.55
8399.79 7886.28
-4746.44 -5734.53
9154.36 -3546.40
-3792.21 -7164.91
-1565.25 -7721.91
-3795.18 -7493.79

原文地址:https://www.cnblogs.com/lifehappy/p/12698981.html