码迷,mamicode.com
首页 > 编程语言 > 详细

平面凸包Graham算法

时间:2018-02-24 14:51:33      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:getch   cstring   def   .com   source   一个   pre   ast   read   

板题hdu1348Wall

平面凸包问题是计算几何中的一个经典问题
具体就是给出平面上的多个点,求一个最小的凸多边形,使得其包含所有的点

具体形象就类似平面上有若干柱子,一个人用绳子从外围将其紧紧缠绕一圈

Graham算法

直接讲算法
我们将所有点排序,分别求出上凸壳和下凸壳,合起来就是凸包
以上凸壳为例子,我们先将最左边的点加入凸包【可以想象,最左侧的点一定在凸包上】
之后向后查找:
1、若当前凸包内只有一点,那么加入新的点
2、如果当前凸包内不止一个点,检验新加入的点与凸包最后一个点所在直线与当前凸包最后两点坐在直线的关系
如果是这样:
技术分享图片
满足上凸性,加入凸包
但是如果是这样:
技术分享图片
不满足上凸性,就不加入
具体判断可以用斜率也可以用叉乘【我写斜率狂WA,还是叉乘比较滋滋】

扫过一遍,就可以得到上凸壳,下凸壳类似

复杂度\(O(nlogn)\)

hdu1348

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
using namespace std;
const int maxn = 2005,maxm = 100005;
const double INF = 1000000000000000000ll;
inline int read(){
    int out = 0,flag = 1; char c = getchar();
    while (c < 48 || c > 57) {if (c == ‘-‘) flag = -1; c = getchar();}
    while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - ‘0‘; c = getchar();}
    return out * flag;
}
const double pi = acos(-1);
struct point{double x,y;}p[maxn];
inline bool operator <(const point& a,const point& b){
    return a.x == b.x ? a.y < b.y : a.x < b.x;
}
inline point operator -(const point& a,const point& b){
    return (point){a.x - b.x,a.y - b.y};
}
inline double operator *(const point& a,const point& b){
    return a.x * b.y - a.y * b.x;
}
inline double dis(int u,int v){
    return sqrt((p[u].x - p[v].x) * (p[u].x - p[v].x) + (p[u].y - p[v].y) * (p[u].y - p[v].y));
}
int T,n,L,q[maxn],tail;
void cal(){
    sort(p + 1,p + 1 + n);
    q[tail = 1] = 1;
    for (int i = 2; i <= n; i++){
        while (tail > 1 && (p[i] - p[q[tail]]) * (p[q[tail]] - p[q[tail - 1]]) < 0) tail--;
        q[++tail] = i;
    }
    int last = tail;
    for (int i = n - 1; i; i--){
        while (tail > last && (p[i] - p[q[tail]]) * (p[q[tail]] - p[q[tail - 1]]) < 0) tail--;
        q[++tail] = i;
    }
}
void print(){
    double ans = 0;
    for (int i = 1; i < tail; i++) ans += dis(q[i],q[i + 1]);
    ans +=  2.0 * pi * L;
    if (T) printf("%.0lf\n\n",ans);
    else printf("%.0lf\n",ans);
}
int main(){
    T = read();
    while (T--){
        n = read(); L = read();
        for (int i = 1; i <= n; i++) p[i].x = read(),p[i].y = read();
        cal();
        print();
    }
    return 0;
}

平面凸包Graham算法

标签:getch   cstring   def   .com   source   一个   pre   ast   read   

原文地址:https://www.cnblogs.com/Mychael/p/8465384.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!