1. 程式人生 > >Poj 1113 Wall (凸包Graham水平序)

Poj 1113 Wall (凸包Graham水平序)

以前做過的題,現在重新寫下。

以前的解題報告:http://blog.csdn.net/whyorwhnt/article/details/8316442

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const double PI=acos(-1.0);
const double eps=1e-8;
const int N=1005;

struct Point  //點,向量
{
    double x,y;
    Point(){}
    Point(double _x,double _y)
    {x=_x;y=_y;}
    void Get ()
    {scanf("%lf%lf",&x,&y);}

    Point operator-(const Point &b)const
    {return Point(x-b.x,y-b.y);}

    Point operator+(const Point &b)
    {return Point(x+b.x,y+b.y);}

    Point operator*(const double k)  //數乘
    {return Point(x*k,y*k);}

    double operator*(const Point a)  //點乘
    {return x*a.x+y*a.y;}

    double operator^(const Point a)  //叉乘
    {return x*a.y-y*a.x;}

    int DB (double dx)  //判0函式
    {
        if(fabs(dx)<eps) return 0;
        return dx>0?1:-1;
    }
    //呼叫點a的該函式
    //返回1點a在向量bc的左側
    //返回-1點a在向量bc的右側
    //返回0點a在向量bc這條直線上
    int Cross (Point b,Point c)
    {return DB((b.x-x)*(c.y-y)-(c.x-x)*(b.y-y));}

    bool operator < (const Point &b)const //用於排序
    {
        if (fabs(y-b.y)<eps) return x-b.x<0;
        return y-b.y<0;
    }

    double Dis (Point ch)
    {return sqrt((x-ch.x)*(x-ch.x)+(y-ch.y)*(y-ch.y));}
}pt[N],ch[N];

int n,len;

//求凸包函式
//pt:所有的點,n個,pt[0]到pt[n-1]
//ch:求完的凸包中的點,len個,q[0]到q[len-1]
void Graham (Point pt[],Point ch[],int &len,int n)      //只儲存凸包頂點
{
	int i,top=1;
	sort(pt,pt+n);
    ch[0]=pt[0];
    ch[1]=pt[1];
    for (i=2;i<n;i++)
    {
        while (top>0 && ch[top-1].Cross(ch[top],pt[i]) <= 0)
            top--;
        ch[++top]=pt[i];
    }
    int temp=top;
    for (i=n-2;i>=0;i--)
    {
        while (top>temp && ch[top-1].Cross(ch[top],pt[i]) <= 0)
            top--;
        ch[++top]=pt[i];
    }
    len=top;
}

int main ()
{
    int L,i,n,len;
    double ans=0;
    scanf("%d%d",&n,&L);
    for (i=0;i<n;i++)
        pt[i].Get();
    Graham (pt,ch,len,n);
    for (i=0;i<len;i++)
        ans+=ch[i].Dis(ch[(i+1)%len]);
    ans+=PI*2*L;
    printf("%.0lf\n",ans);
    return 0;
}