UVA1303 【Wall】Solution

版权声明://By Oier ScapeGoatTree https://blog.csdn.net/u014553430/article/details/84644521

为您读题:

T组数据,每组有n,L,和给定的n组整数数对。整数数对表示点的坐标。求:一个周长最小的几何图形,使得该图形上任何一点到原点对构成的多边形的距离都不小于L。

为您解析:

  • 既然是不小于,那么我们当然取等于。
  • 在一条边外距离为L的是和该边构成矩形的一条平行边

拐角怎么办?

- 一种想法是:我们使得拐角处图形的任何一处到该拐点的距离都是L
- 这构成了一个圆弧
- 多边形的拐角(即为外角和)永远是360°,所以我们在统计答案的时候加上$2*\pi*L$即可。

为你答疑:

万一是个凹多边形怎么办呢?

再如图所示
qwq

如果我们让城墙随着D点的凹陷而拐进去,会发现反而不如直接连接与圆E和圆N的城墙拐点,因为三角形两边之和大于第三边。

我们发现,直线的城墙,每条边都和城堡的边长一样啊,这不就是一个凸包吗?

于是,问题被转化成了求二维凸包的问题。

为你提示:

这道题有点抽风,UVA给定的要求是每两个答案之间空一行并且文末只有一个换行。

特判剩余组数T即可。

为你打码(大雾):

#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
struct point
{
    double x,y;
};
point all[2000],chose[2000];
inline point operator -(const point& a,const point& b)
{return (point){a.x-b.x,a.y-b.y};}
inline double operator *(const point& a,const point& b)
{return a.x*b.y-a.y*b.x;}
inline double dis(point a,point b)
{return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}

bool cmp(point a,point b)
{
    return (a.x==b.x)?(a.y<b.y):(a.x<b.x);
}//按照横坐标排序 
int INCLUDE(int n)
{
    //上下求两个凸壳
    int m=1;
    chose[1]=all[1];
    for(int i=2;i<=n;i++)
    {
        while(m>1&&(all[i]-chose[m])*(chose[m]-chose[m-1])<0) m--;
        chose[++m]=all[i];
    }
    int last=m;
    for(int i=n-1;i>0;i--)
    {
        while(m>last&&(all[i]-chose[m])*(chose[m]-chose[m-1])<0) m--;
        chose[++m]=all[i];
    }
    if(m>1) m--;
    return m;
}
inline int read()
{
    int n=0,k=1;
    char c=getchar();
    while(c>'9'||c<'0') {if(c=='-') k=-1; c=getchar();}
    while(c<='9'&&c>='0') {n=(n<<1)+(n<<3)+(c^48); c=getchar();	}
    return n*k;
}
int n,mm,T;
inline void prtans(int m)
{
    double ans=0;
    for(int i=1;i<=m;i++)
    {
        ans+=dis(chose[i],chose[i+1]);
    }
    ans+= 2.0*pi*mm;
    if(T) printf("%.0lf\n\n",ans);
    else printf("%.0lf\n",ans);
}

int main()
{
    T=read();
    while(T--)
    {
        n=read();
        mm=read();
        for(int i=1;i<=n;i++)
        {
            all[i].x=read();
            all[i].y=read();
        }
        stable_sort(all+1,all+n+1,cmp);
        int tot=INCLUDE(n);
        prtans(tot);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u014553430/article/details/84644521