| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 30701 | Accepted: 10340 |
Description

Input
Output
Sample Input
9 100 200 400 300 400 300 300 400 300 400 400 500 400 500 200 350 200 200 200
Sample Output
1628
Hint
Source
求出围住这个城堡的围墙的最小值,围墙距离城堡最低不能小于l
所以结果= 城堡的凸包边长 + l的圆周长。
在这个题中求凸包的时候,进行极角排序->压入节点->分类如果mul(q2,q1,p[i]) = 1 直接压入->= 0 抛出栈首的节点,压入新节点-> = -1只抛出栈首的节点i--。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <cmath>
using namespace std ;
#define eps 1e-8
#define PI 3.141592653589793238462643383279502884197169399375105820974944
struct node{
double x , y ;
}p[11000] , q , q1 , q2 ;
stack <node> sta ;
node sub(node a,node b)
{
a.x -= b.x ;
a.y -= b.y ;
return a ;
}
int mul(node q,node a,node b)
{
a = sub(a,q) ;
b = sub(b,q) ;
double x = a.x*b.y - a.y*b.x ;
if( fabs(x) < eps )
return 0 ;
else if( x > 0 )
return 1 ;
return -1 ;
}
int dis(node q,node a,node b)
{
a = sub(a,q) ;
b = sub(b,q) ;
double k1 = a.x*a.x + a.y*a.y , k2 = b.x*b.x + b.y*b.y ;
if( fabs(k1-k2) < eps )
return 0 ;
else if( k1-k2 > eps )
return 1 ;
return -1 ;
}
int cmp(node a,node b)
{
int k1 = mul(q,a,b) , k2 = dis(q,a,b) ;
return k1 == 1 || (k1 == 0 && k2 == -1) ;
}
int main()
{
int n , i , j ;
double r , ans ;
while( scanf("%d %lf", &n, &r) != EOF )
{
q.x = q.y = 11000.0 ;
for(i = 0 ; i < n ; i++)
{
scanf("%lf %lf", &p[i].x, &p[i].y) ;
if( p[i].y < q.y || ( fabs(p[i].y-q.y ) < eps && p[i].x < q.x ) )
q = p[i] ;
}
sort(p,p+n,cmp) ;
while( !sta.empty() ) sta.pop() ;
sta.push(p[0]) ;
sta.push(p[1]) ;
for(i = 2 ; i < n ; i++)
{
//printf("%lf %lf*\n", p[i].x, p[i].y) ;
q1 = sta.top() ;
sta.pop() ;
q2 = sta.top() ;
sta.pop() ;
int k = mul(q2,q1,p[i]) ;
if( k == 1 )
{
sta.push(q2) ;
sta.push(q1) ;
sta.push(p[i]) ;
}
else if( k == 0 )
{
sta.push(q2) ;
sta.push(p[i]) ;
}
else
{
sta.push(q2) ;
i-- ;
}
}
n = 1 ;
while( !sta.empty() )
{
p[n++] = sta.top() ;
//printf("%lf %lf\n", p[n-1].x, p[n-1].y);
sta.pop() ;
}
ans = 2.0*PI*r ;
for(i = 0 ; i < n-1 ; i++)
{
ans += sqrt( (p[i].x-p[i+1].x)*(p[i].x-p[i+1].x)*1.0 + (p[i].y-p[i+1].y)*(p[i].y-p[i+1].y)*1.0 ) * 1.0 ;
}
printf("%.0f\n", ans) ;
}
return 0;
}
原文:http://blog.csdn.net/winddreams/article/details/43265897