Code
//借鉴了一下牛人的程序,终于AC,63MS
//题意:求坐标上的点构成的凸包,不过题目有个难点,就是要将wall距离城堡r远,有公式wall=2*pi*r+len(凸包)
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 1010;
const double pi = acos(-1.0);
typedef struct
{
double x,y;
double thera;
}Point;
vector<Point>p;
int S[MAXN];
bool cmp1(Point &a,Point &b)
{
if( a.y == b.y ) return a.x < b.x;
return a.y < b.y;
}
bool cmp2(Point &a,Point &b)
{
if( a.thera == b.thera ) //极角相同按极半径降序
return sqrt(a.x*a.x+a.y*a.y) > sqrt(b.x*b.x+b.y*b.y);
else return a.thera < b.thera;
}
bool cmp3(const Point &a,const Point &b)
{
return (a.thera == b.thera);
}
bool xmult(Point p0, Point p1, Point p2)
{
int xa = p1.x-p0.x, ya = p1.y-p0.y,
xb = p2.x-p1.x, yb = p2.y-p1.y;
if (!(xa*yb - xb*ya < 0))
return true;
else
return false;
}
double dis(Point p1,Point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double graham_scan()
{
int i,num = p.size();
Point *t;
sort(p.begin(),p.end(),cmp1);
Point p0 = p[0];
for( i = 0 ; i < p.size() ; i ++ )
{
p[i].x -= p0.x; p[i].y -= p0.y;
p[i].thera = atan2(1.0*p[i].y,1.0*p[i].x);//算出i点与原点构成直线和x轴夹角
}
sort(p.begin()+1,p.end(),cmp2);
vector<Point>::iterator itr = unique(p.begin()+1,p.end(),cmp3);
if( itr != p.end() )
{
p.erase(itr,p.end());
num = p.size();
}
int top = -1;
S[++top] = 0;
S[++top] = 1;
S[++top] = 2;
for( i = 3 ; i < num ; i ++ )//grahamScan扫描法
{
while( xmult(p[S[top-1]],p[S[top]],p[i]) == false )
--top;
S[++top] = i;
}
for( i = 0 ; i <= top ; i ++ )
{
p[S[i]].x += p0.x;
p[S[i]].y += p0.y;
//printf("%.lf,%.lf\n",p[S[i]].x,p[S[i]].y);
}
double ans = dis(p[S[0]],p[S[top]]);//计算凸包长度
for( i = 1 ; i <= top ; i ++ )
{
ans += dis(p[S[i]],p[S[i-1]]);
}
return ans;
}
int main()
{
int N,i;
double x,y,r;
Point t;
//freopen("1113.txt","r",stdin);
while( scanf("%d %lf",&N,&r) != EOF )
{
for( i = 0 ; i < N ; i ++ )
{
scanf("%lf %lf",&t.x,&t.y);
p.push_back(t);
}
double ans = graham_scan();
ans += 2.0*pi*r;
printf("%.lf\n",ans);
}
return 0;
}
//借鉴了一下牛人的程序,终于AC,63MS
//题意:求坐标上的点构成的凸包,不过题目有个难点,就是要将wall距离城堡r远,有公式wall=2*pi*r+len(凸包)
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 1010;
const double pi = acos(-1.0);
typedef struct
{
double x,y;
double thera;
}Point;
vector<Point>p;
int S[MAXN];
bool cmp1(Point &a,Point &b)
{
if( a.y == b.y ) return a.x < b.x;
return a.y < b.y;
}
bool cmp2(Point &a,Point &b)
{
if( a.thera == b.thera ) //极角相同按极半径降序
return sqrt(a.x*a.x+a.y*a.y) > sqrt(b.x*b.x+b.y*b.y);
else return a.thera < b.thera;
}
bool cmp3(const Point &a,const Point &b)
{
return (a.thera == b.thera);
}
bool xmult(Point p0, Point p1, Point p2)
{
int xa = p1.x-p0.x, ya = p1.y-p0.y,
xb = p2.x-p1.x, yb = p2.y-p1.y;
if (!(xa*yb - xb*ya < 0))
return true;
else
return false;
}
double dis(Point p1,Point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double graham_scan()
{
int i,num = p.size();
Point *t;
sort(p.begin(),p.end(),cmp1);
Point p0 = p[0];
for( i = 0 ; i < p.size() ; i ++ )
{
p[i].x -= p0.x; p[i].y -= p0.y;
p[i].thera = atan2(1.0*p[i].y,1.0*p[i].x);//算出i点与原点构成直线和x轴夹角
}
sort(p.begin()+1,p.end(),cmp2);
vector<Point>::iterator itr = unique(p.begin()+1,p.end(),cmp3);
if( itr != p.end() )
{
p.erase(itr,p.end());
num = p.size();
}
int top = -1;
S[++top] = 0;
S[++top] = 1;
S[++top] = 2;
for( i = 3 ; i < num ; i ++ )//grahamScan扫描法
{
while( xmult(p[S[top-1]],p[S[top]],p[i]) == false )
--top;
S[++top] = i;
}
for( i = 0 ; i <= top ; i ++ )
{
p[S[i]].x += p0.x;
p[S[i]].y += p0.y;
//printf("%.lf,%.lf\n",p[S[i]].x,p[S[i]].y);
}
double ans = dis(p[S[0]],p[S[top]]);//计算凸包长度
for( i = 1 ; i <= top ; i ++ )
{
ans += dis(p[S[i]],p[S[i-1]]);
}
return ans;
}
int main()
{
int N,i;
double x,y,r;
Point t;
//freopen("1113.txt","r",stdin);
while( scanf("%d %lf",&N,&r) != EOF )
{
for( i = 0 ; i < N ; i ++ )
{
scanf("%lf %lf",&t.x,&t.y);
p.push_back(t);
}
double ans = graham_scan();
ans += 2.0*pi*r;
printf("%.lf\n",ans);
}
return 0;
}