凸包 poj 1113

求一个多边形  拐弯的地方用圆弧补上

距离>=l

求他的周长

求一个凸包的周长  加2*pi*l

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<stack>
#include<math.h>
using namespace std;

#define MAXN 1010
#define pi 4*atan(1.0)
class point
{
public:
    int x,y;
    point operator -(point b)
    {
        point c;
        c.x=x-b.x;
        c.y=y-b.y;
        return c;
    }
    int operator ^ (point b)
    {
        return x*b.y-y*b.x;
    }
};
point x[MAXN];
point ans[MAXN];
stack<point>z;

double dis(point a,point b)
{
    return sqrt(double((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
}
bool cmp(point a,point b)
{
    int tmp=((a-x[0])^(b-x[0]));
    if(tmp>0)
        return 1;
    else if(tmp==0&&dis(x[0],a)<dis(x[0],b))
        return 1;
    return 0;
}
int main()
{
    int n,l;
    while(scanf("%d%d",&n,&l)!=EOF)
    {
        while(!z.empty())
            z.pop();
        int k=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&x[i].x,&x[i].y);
            if(x[i].y<x[k].y)//维护一个左下角的点
                k=i;
            else if(x[i].y==x[k].y&&x[i].x<x[k].x)
                k=i;
        }
        swap(x[0],x[k]);//交换
        sort(x+1,x+n,cmp);//极角排序
        z.push(x[0]); //扫描法
        z.push(x[1]);
        point a,b;
        for(int i=2;i<n;i++)
        {
            b=z.top();
            z.pop();
            a=z.top();
            while(z.size()>1&&((x[i]-b)^(b-a)) >=0)
            {
                b=a;
                z.pop();
                a=z.top();
            }
            z.push(b);
            z.push(x[i]);
        }
        int len=0;
        while(!z.empty())
        {
            ans[len++]=z.top();
            z.pop();
        }
        double ans1=0;
        for(int i=0;i<len-1;i++)
            ans1+=dis(ans[i],ans[i+1]);
        ans1+=dis(ans[len-1],ans[0]);
        ans1+=2*pi*l;
        printf("%d
",(int)(ans1+0.5));//求和4舍5入
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cherryMJY/p/6283196.html