计算几何练习集

 // 2019.8.13

 // 昨天的内容是计算几何部分点、线、多边形、向量、凸包等基本概念的介绍和模板的引入,之前的博客已有涉及,不再重复记录。

 // 今天同样是ddy带来了计算几何进阶知识点的讲解。

凸包

 凸包模板,HDU1392 求凸包周长

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 110;
typedef double db;
struct P {
    db x, y;
    P(db x=0, db y=0):x(x), y(y) {}
    P operator-(const P& a) {
        return P(x-a.x, y-a.y);
    }
    P operator+(const P& a) {
        return P(x+a.x, y+a.y);
    }
    P operator*(const db a) {
        return P(a*x, a*y);
    }
    double len() {
        return sqrt(x*x+y*y);
    }
    void print() {
        printf("(%.2lf %.2lf)\n", x, y);
    }
}node[maxn];
int n;

// 向量a,b叉积 a×b
db cross(const P& a, const P& b) {
    return a.x*b.y - b.x*a.y;
}

// 凸包
P stack[maxn];
int top;   // 凸包上点个数

bool cmp(P a, P b) {
    db x = cross(a-node[0], b-node[0]);
    if(x>0) return 1;
    if(x==0) return (a-node[0]).len()<(b-node[0]).len();
    return 0;
}

// 返回凸包上点的个数
// 点按逆时针放入stack
double graham() {
    // 1. 找到最左下方的点
    int k=0;
    for(int i=1;i<n;i++) {
        if(node[i].y<node[k].y || node[i].y==node[k].y && node[i].x<node[k].x)
            k = i;
    }
    swap(node[0], node[k]);

    // 2. 按照极角排序
    sort(node+1, node+n, cmp);
/*    for(int i=0;i<n;i++) {
        node[i].print();
    }
*/
    // 3. 保存凸包上的点
    stack[0] = node[0];
    stack[1] = node[1];
    int top = 1;
    for(int i=2;i<n;i++) {
        while(top>=1 && cross(stack[top]-stack[top-1], node[i]-stack[top-1])<=0) --top;
        stack[++top] = node[i];
    }
    stack[++top] = stack[0];
    double ans = 0;
    for(int i=1;i<=top;i++) {
        ans += (stack[i]-stack[i-1]).len();
    }
    return ans;
}


int main() {
    while(scanf("%d", &n)!=EOF && n) {
        for(int i=0;i<n;i++) {
            scanf("%lf %lf", &node[i].x, &node[i].y);
        }
        if(n==1) printf("0.00\n");
        // n==2居然要特判。。。什么傻逼
        else if(n==2) printf("%.2lf\n", (node[0]-node[1]).len());
        else
            printf("%.2lf\n",  graham());
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/izcat/p/11349114.html