poj1113 Wall

来源:互联网 发布:食品数据分析咨询公司 编辑:程序博客网 时间:2024/06/05 09:42

Wall
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 35478 Accepted: 12090

Description

Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he would not listen to his Architect's proposals to build a beautiful brick wall with a perfect shape and nice tall towers. Instead, he ordered to build the wall around the whole castle using the least amount of stone and labor, but demanded that the wall should not come closer to the castle than a certain distance. If the King finds that the Architect has used more resources to build the wall than it was absolutely necessary to satisfy those requirements, then the Architect will loose his head. Moreover, he demanded Architect to introduce at once a plan of the wall listing the exact amount of resources that are needed to build the wall. 

Your task is to help poor Architect to save his head, by writing a program that will find the minimum possible length of the wall that he could build around the castle to satisfy King's requirements. 

The task is somewhat simplified by the fact, that the King's castle has a polygonal shape and is situated on a flat ground. The Architect has already established a Cartesian coordinate system and has precisely measured the coordinates of all castle's vertices in feet.

Input

The first line of the input file contains two integer numbers N and L separated by a space. N (3 <= N <= 1000) is the number of vertices in the King's castle, and L (1 <= L <= 1000) is the minimal number of feet that King allows for the wall to come close to the castle. 

Next N lines describe coordinates of castle's vertices in a clockwise order. Each line contains two integer numbers Xi and Yi separated by a space (-10000 <= Xi, Yi <= 10000) that represent the coordinates of ith vertex. All vertices are different and the sides of the castle do not intersect anywhere except for vertices.

Output

Write to the output file the single number that represents the minimal possible length of the wall in feet that could be built around the castle to satisfy King's requirements. You must present the integer number of feet to the King, because the floating numbers are not invented yet. However, you must round the result in such a way, that it is accurate to 8 inches (1 foot is equal to 12 inches), since the King will not tolerate larger error in the estimates.

Sample Input

9 100200 400300 400300 300400 300400 400500 400500 200350 200200 200

Sample Output

1628

Hint

结果四舍五入就可以了

题意:依次顺时针给你N个点,这N个点所围成的图形就是城堡。然后给你L,表示所建的城墙距离城堡上的每个点的最小距离是L。

思路:围绕城堡边缘做距离为L平行线,这个不难想,此时的城墙已经包含的最短长度,自然是所给点所组成的凸包的周长。剩下的关键是怎么围起来。


绿色的表示上面已经说得。连接起来的时候我们用弧,以那个角端点为圆心(图上是深绿色的点),以L为半径(紫色)画弧,此时围墙的长度不可能比这还小的,而这种情况是符合条件的,所以最小城墙长度=N个点所围成的凸包的周长+半径为L的圆的周长。这里为什么是一个圆呢?读者可以仔细想一下的,它的每一段弧的圆心角都是对应着一个凸包的外角的。

注意:

1.题目上只说按照顺时针给出点,所以建立凸包的时候,点依旧要先排序。(我贡献了好多的WA   QAQ)后来仔细一想,就是上面的图如果从第三个点给....QAQ。

2.最后的结果四舍五入即可。

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include<iomanip>using namespace std;const int inf=0x3f3f3f;const double pi=acos(-1);const int MAXN=1000+5;struct node{    int x,y;}p[MAXN],p0;int n,l;//ab叉乘cdint det(int x1,int y1,int x2,int y2){    return x1*y2-x2*y1;}int cross(node a,node b,node c,node d){     return det(b.x-a.x,b.y-a.y,d.x-c.x,d.y-c.y);}int t[MAXN];//快排比较函数int dis(node a,node b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}int cmp(node a,node b){    int temp=cross(p0,a,p0,b);    if(temp)    {        return temp>0;    }    else return dis(p0,a)-dis(p0,b)<0;}int main(){    int i;    scanf("%d%d",&n,&l);    int mx=inf,pos=0;    for(i=0;i<n;++i)    {        scanf("%d%d",&p[i].x,&p[i].y);        if(p[i].x<mx)        {            mx=p[i].x;            pos=i;        }        else if(p[i].x==mx)        {            if(p[i].y<p[pos].y)            {                pos=i;            }        }    }    p0=p[pos];    sort(p,p+n,cmp);    p[n]=p[0];//封闭凸包    int top=0;    t[top]=0;    t[++top]=1;    for(i=2;i<=n;)    {        if(cross(p[t[top-1]],p[t[top]],p[t[top]],p[i])>=0)        {            t[++top]=i++;        }        else top--;    }    double sum=0;    //计算距离    for(i=0;i<top;++i)    {        sum+=hypot(p[t[i]].x-p[t[i+1]].x,p[t[i]].y-p[t[i+1]].y);    }    sum+=2*pi*l;    int ans=sum+0.5;//结果四舍五入    printf("%d\n",ans);    return 0;}



1 0
原创粉丝点击