POJ1113 凸包周长计算

题目大意:给出n个点的坐标,计算这些点的凸包的周长,但是还需要加上一些距离,因为它规定城墙必须离给定的点(城堡)一定得距离m.


思路:上面说的比较明白了,其实直接套用模板就好了,当然要加上的圆的距离只是一个圆就好了,这个大家画个图就能够发现,三角形,矩形,加上的都是一个圆,这个是可以证明的,大家去找规律就好了。 我这里是用模板算出了所有的点,然后再一条一条的算距离(模板里没有……)


AC 代码:



#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <climits>
#include<vector>
#include<iomanip>
#include <numeric>
#include<cmath>
#define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define REP(i,n) for(int i=0;i<n;++i)
using namespace std;

const double EPS = 1e-8;
inline int sign(double a)
{
    return a < -EPS ? -1 : a > EPS;
}

struct Point
{
    double x, y;
    Point()
    {
    }
    Point(double _x, double _y) :
        x(_x), y(_y)
    {
    }
    Point operator+(const Point&p) const
    {
        return Point(x + p.x, y + p.y);
    }
    Point operator-(const Point&p) const
    {
        return Point(x - p.x, y - p.y);
    }
    Point operator*(double d) const
    {
        return Point(x * d, y * d);
    }
    Point operator/(double d) const
    {
        return Point(x / d, y / d);
    }
    bool operator<(const Point&p) const
    {
        int c = sign(x - p.x);
        if (c)
            return c == -1;
        return sign(y - p.y) == -1;
    }
    double dot(const Point&p) const
    {
        return x * p.x + y * p.y;
    }
    double det(const Point&p) const
    {
        return x * p.y - y * p.x;
    }
    double alpha() const
    {
        return atan2(y, x);
    }
    double distTo(const Point&p) const
    {
        double dx = x - p.x, dy = y - p.y;
        return hypot(dx, dy);
    }
    double alphaTo(const Point&p) const
    {
        double dx = x - p.x, dy = y - p.y;
        return atan2(dy, dx);
    }
    void read()
    {
        scanf("%lf%lf", &x, &y);
    }
    double abs()
    {
        return hypot(x, y);
    }
    double abs2()
    {
        return x * x + y * y;
    }
    void write()
    {
        cout << "(" << x << "," << y << ")" << endl;
    }
};

#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))

#define crossOp(p1,p2,p3) sign(cross(p1,p2,p3))

Point isSS(Point p1, Point p2, Point q1, Point q2)       //可求p1,p2 直线与q1,q2的焦点。。不过不确定
{
    double a1 = cross(q1,q2,p1), a2 = -cross(q1,q2,p2);
    Point temp;
    temp.x=sign((p1.x*a2+p2.x*a1)/(a1+a2))==0?0:(p1.x*a2+p2.x*a1)/(a1+a2);
    temp.y=sign((p1.y*a2+p2.y*a1)/(a1+a2))==0?0:(p1.y*a2+p2.y*a1)/(a1+a2);
    return temp;
}


vector<Point> convexHull(vector<Point> ps)
{
    int n = ps.size();
    if (n <= 1)
        return ps;
    sort(ps.begin(), ps.end());
    vector<Point> qs;
    for (int i = 0; i < n; qs.push_back(ps[i++]))
    {
        while (qs.size() > 1 && crossOp(qs[qs.size()-2],qs.back(),ps[i]) <= 0)
            qs.pop_back();
    }
    for (int i = n - 2, t = qs.size(); i >= 0; qs.push_back(ps[i--]))
    {
        while (qs.size() > t && crossOp(qs[qs.size()-2],qs.back(),ps[i]) <= 0)
            qs.pop_back();
    }
    qs.pop_back();
    return qs;
}

int main()
{
    int n,m;
    cin>>n>>m;
    vector<Point>ps;
    vector<Point>qs;
    Point temp;
    for(int i=1; i<=n; i++)
    {
        temp.read();
        ps.push_back(temp);
    }
    qs=convexHull(ps);
    int l=qs.size();
    double sum=0;
    for(int i=0;i<l;i++)
    {
        sum+=qs[i].distTo(qs[(i+1)%l]);
    }
    sum+=2*3.14159265*m;
    cout<<fixed<<setprecision(0)<<sum<<endl;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值