POJ 1113(凸包入门题)

题意:

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

思路:

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

作为入门题还是不错的。

代码:
#include <cmath>
#include <cstdio>
#include <algorithm>
#define S first
#define E second
#define eps 1e-8
using 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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值