简单凸包

来源:互联网 发布:有网络但下载速度为零 编辑:程序博客网 时间:2024/05/29 03:18

凸包:

平面内有n个点,选取最外面的点并连接,得到的凸多边形就是凸包。

graham算法:

选取最左端与最右端的两个点,然后从左到右扫一遍,再从右到左扫一遍,分别建立凸包的上侧与下侧。


实现过程:

1.将各点按横坐标的值排序;

2.从第一个点到最后一个点,正向反向分别遍历一次,通过比较斜率来取舍外围点。

例题:

poj : http://poj.org/problem?id=2187

AC代码:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int M = 50020;struct Point{    int x, y;    bool operator < (const Point &i) const    {        if(x == i.x)            return y < i.y;        return x < i.x;    }}dx[M], out[M];bool gradjudge(Point a, Point b, Point c){    int t1 = (a.x - b.x) * (c.y - b.y);    int t2 = (a.y - b.y) * (c.x - b.x);    return t1 >= t2;}int dist(Point a, Point b){    int res = (a.y - b.y) * (a.y - b.y) + (a.x - b.x) * (a.x - b.x);    return res;}main(){    int n, k;    while(~scanf("%d", &n))    {        for(int i = 0; i < n; i++)            scanf("%d %d", &dx[i].x, &dx[i].y);        sort(dx, dx + n);        k = 0;        for(int i = 0; i < n; i++)        {            while(k > 1 && !gradjudge(out[k - 2], out[k - 1], dx[i]))                k--;            out[k++] = dx[i];        }        int t = k;        for(int i = n - 2; i >= 0; i--)        {            while(k > t && !gradjudge(out[k - 2], out[k - 1], dx[i]))                k--;            out[k++] = dx[i];        }        int res = 0;        for(int i = 0; i < k; i++)            for(int j = i + 1; j < k; j++)                res = max(res, dist(out[i], out[j]));        printf("%d\n", res);    }}/*40 00 11 11 050 01 12 20 22 0100 010000 01 1002 1999999 1009998 199100 -900200 -17999800 -17999900 -900*//*28100000000*/


0 0
原创粉丝点击