POJ 1113(凸包入门题)

来源:互联网 发布:国外网络电视在线直播 编辑:程序博客网 时间:2024/06/07 05:13

题意:

n 个点,要求一个环形把所有的点都包围起来,并且使得环形距所有点的距离至少为 L,求最小的环形的周长?

思路:

凸包求解,其实看完题目给的图片,就知道答案就是 = 凸包周长 + 2πL
凸包求解学习资料,建议先看一下 这个,然后读代码的时候就很简单了!

作为入门题还是不错的。

代码:

#include <cmath>#include <cstdio>#include <algorithm>#define S first#define E second#define eps 1e-8using namespace std;const int N = 1e3 + 10;const double PI = acos(-1.0);typedef double TP;struct Point{    TP x, y;    Point(TP x = 0, TP y = 0) :x(x), y(y){}    void input()    {        scanf("%lf %lf", &x, &y);    }    Point operator - (const Point& p)    {        return Point(x - p.x, y - p.y);    }    TP operator ^ (const Point& p)    {        return (x * p.y - y * p.x);    }};int dcmp(double x){      if(fabs(x) < eps) return 0;      else return x < 0 ? -1 : 1;  }TP cross(Point& S, Point& E, Point& O){    return (S - O) ^ (E - O);}double dis(Point& a, Point& b){    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}bool pointCmp(const Point& a, const Point& b){    if(dcmp(a.x - b.x) == 0) return a.y < b.y;    return a.x < b.x;}void convexHull(Point *p, int n, Point *C, int& m){    sort(p, p + n, pointCmp);    m = 0;    for(int i = 0;i < n;i ++) {        while(m > 1 && cross(C[m-1], p[i], C[m-2]) <= 0) m --;        C[m ++] = p[i];    }    int k = m;    for(int i = n - 2;i >= 0;i --) {        while(m > k && cross(C[m-1], p[i], C[m-2]) <= 0) m --;        C[m ++] = p[i];    }    if(m > 1) m --;}int n, m;Point p[N], C[N];int main(){    int l;    scanf("%d%d", &n, &l);    for(int i = 0;i < n;i ++) p[i].input();    convexHull(p, n, C, m);    double ans = 2 * PI * l;    for(int i = 0;i < m;i ++) {        ans += dis(C[i], C[(i + 1) % m]);    }    printf("%d\n", int(ans + 0.5));    return 0;}
0 0
原创粉丝点击