poj 1113 Wall

http://poj.org/problem?id=1113

题目大意

国王给自己的城堡建围墙,围墙要和城堡保持一定距离L

凸包,保持一定的距离只不过多了一个圆弧长度而已(PI*2*L)

因为所有拐点处的圆弧加在一起是一个圆

#include<iostream>

#include<cmath>

#include<string>

#include<algorithm>

#include<queue>

#include<cstring>

#include<cstdio>



using namespace std;

const double PI=acos(-1);

const int N=1005;

struct node

{

    int x,y;

}mem[N];

int used_point[N];

double dist(int i,int j)//求两点距离

{

    return sqrt((mem[i].x-mem[j].x)*(mem[i].x-mem[j].x)

                +(mem[i].y-mem[j].y)*(mem[i].y-mem[j].y));

}

bool cmp(node l1,node l2)//叉积排序 如果相等 近的优先

{

    if((l1.x-mem[0].x)*(l2.y-mem[0].y)==(l2.x-mem[0].x)*(l1.y-mem[0].y))

    return ((l1.x-mem[0].x)*(l1.x-mem[0].x)+(l1.y-mem[0].y)*(l1.y-mem[0].y))<

    ((mem[0].x-l2.x)*(mem[0].x-l2.x)+(mem[0].y-l2.y)*(mem[0].y-l2.y));

    return (l1.x-mem[0].x)*(l2.y-mem[0].y)>(l2.x-mem[0].x)*(l1.y-mem[0].y);

}

bool Left_turn(int i,int j,int l)//判断是否左转

{

    int x1=mem[j].x-mem[i].x;

    int y1=mem[j].y-mem[i].y;

    int x2=mem[l].x-mem[j].x;

    int y2=mem[l].y-mem[j].y;

    if(x1*y2>x2*y1)//如果左转 true (这种情况为不要直线上多余的点 如果想要应用 >=)

    return true;

    return false;

}

int main()

{

    int n,l;

    while(scanf("%d %d",&n,&l)!=EOF)

    {

        int k=0;

        for(int i=0;i<n;++i)

        {

            scanf("%d %d",&mem[i].x,&mem[i].y);

            if(mem[i].y<mem[k].y||(mem[i].y==mem[k].y&&mem[i].x<mem[k].x))

            k=i;

        }

        if(k!=0)

        {

             swap(mem[0].x,mem[k].x);

             swap(mem[0].y,mem[k].y);

        }

        sort(mem+1,mem+n,cmp);

        int I=0;

        used_point[I++]=0;

        used_point[I++]=1;

        used_point[I++]=2;

        for(int i=3;i<n;)

        {

            if(I<2||Left_turn(used_point[I-2],used_point[I-1],i))//是左转则入栈加一 (I<2)的情况是对于开始就有直线又不要直线上多余点的情况,

            //防止越界。如果直线上多余的点也要则可不写,但会有多余的点使得效率低

            used_point[I++]=i++;

            else//否则出栈

            --I;

        }

        used_point[I]=used_point[0];

        double ans=0.0;

        for(int i=0;i<I;++i)

        {

            ans=ans+dist(used_point[i],used_point[i+1]);

        }

        ans=ans+(PI*2*l);

        printf("%d\n",int(ans+0.5));

    }

    return 0;

}





 

 

你可能感兴趣的:(poj)