POJ 1113 Wall

由图可知 路径长度就是图包+一个以L为半径的圆

四舍五入很玄学。。。

/*
    取一个最第点 极角排序 类似单调队列地删点
*/
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e4+50;
const double eps=1e-7;
const double Pi=acos(-1);
struct Point
{
    double x,y; Point(){}
    Point(double _x,double _y){x=_x,y=_y;};
}p[N],q[N];
Point operator - (Point A,Point B) {return Point(A.x-B.x,A.y-B.y);} 
double operator * (Point A,Point B) {return A.x*B.x+A.y*B.y;} 
double operator ^ (Point A,Point B) {return A.x*B.y-A.y*B.x;} 
double dist(Point A,Point B) {return sqrt((A-B)*(A-B));} 
bool cmp(Point a,Point b)
{
    double c=(a-p[1])^(b-p[1]);
    if(fabs(c)<=eps) return dist(a,p[1])<dist(b,p[1]);
    return c<eps;
}
int main()
{
    int n,r; scanf("%d%d",&n,&r);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&p[i].x,&p[i].y);
        if(i>1&&p[i].y<p[1].y) swap(p[i],p[1]);
    }
    sort(p+2,p+n+1,cmp);
    q[1]=p[1]; int ed=1;
    for(int i=2;i<=n;i++)
    {
        while(ed>1&&((p[i]-q[ed-1])^(q[ed]-q[ed-1]))<=eps) ed--;
        q[++ed]=p[i];
    }
    q[ed+1]=p[1]; double res=0;
    for(int i=1;i<=ed;i++) res+=dist(q[i],q[i+1]);
    printf("%d\n",(int)(res+Pi*2*r+0.5)); // 玄学的四舍五入 
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lxy8584099/p/10420103.html