投针问题
计算最大凸包的周长
然后根据投针问题的公式计算,注意,凸包180°旋转的情况是相同的,所以要除以二
/*author: birdstorm*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <complex>
#include <set>
#include <algorithm>
#include <climits>
#define MAXN 105
//#define N 105
#define inf 1.0e20
#define eps 1.0e-14
#define MOD 1000000007
#define next(i) (i+1)%sz
#define For(i,m,n) for(int i=(m);i<(n);i++)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define rep(i,m,n) for(int i=(m);i<=(n);i++)
#define repd(i,m,n) for(int i=(m);i>=(n);i--)
#define LL long long
#define test
using namespace std;
const double pi=acos(-1.0);
template<class T>
inline bool read(T &n)
{
T x = 0, tmp = 1;
char c = getchar();
while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if(c == EOF) return false;
if(c == '-') c = getchar(), tmp = -1;
while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
n = x*tmp;
return true;
}
template <class T>
inline void write(T n)
{
if(n < 0)
{
putchar('-');
n = -n;
}
int len = 0,data[20];
while(n)
{
data[len++] = n%10;
n /= 10;
}
if(!len) data[len++] = 0;
while(len--) putchar(data[len]+48);
}
struct point
{
double x,y;
point():x(0),y(0) {}
point(double x,double y):x(x),y(y) {}
point operator + (const point &a) const
{
return point(x+a.x,y+a.y);
}
point operator - (const point &a) const
{
return point(x-a.x,y-a.y);
}
bool operator < (const point &a) const
{
return x+eps<a.x || abs(x-a.x)<eps && y+eps<a.y;
}
bool operator == (const point &a) const
{
return abs(x-a.x)<eps && abs(y-a.y)<eps;
}
point operator * (double c) const
{
return point(c*x,c*y);
}
point operator / (double c) const
{
return point(x/c,y/c);
}
};
double det(const point &a, const point &b)
{
return a.x*b.y-a.y*b.x;
}
point zero(0,0);
int dlcmp(double x)
{
return x<-eps?-1:x>eps;
}
double cross(point a, point b)
{
return a.x*b.y-b.x*a.y;
}
double dist(point a, point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
struct Polygon_convex
{
vector<point> P;
Polygon_convex(int Size=0)
{
P.resize(Size);
}
double calc()
{
double ans=0;
int sz=P.size();
P.push_back(P[0]);
For(i,0,sz)
ans+=dist(P[i],P[i+1]);
P.pop_back();
P.resize(sz);
return ans;
}
};
bool cmp_less(const point &a, const point &b)
{
return dlcmp(a.x-b.x)<0||dlcmp(a.x-b.x)==0&&dlcmp(a.y-b.y)<0;
}
Polygon_convex convex_hull(vector<point> a)
{
Polygon_convex res(2*a.size()+5);
sort(a.begin(),a.end(),cmp_less);
a.erase(unique(a.begin(),a.end()),a.end());
int m=0;
for(int i=0; i<a.size(); ++i)
{
while(m>1&&dlcmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<=0)
m--;
res.P[m++]=a[i];
}
int k=m;
for(int i=(int)(a.size())-2; i>=0; i--)
{
while(m>k&&dlcmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<=0)
m--;
res.P[m++]=a[i];
}
res.P.resize(m);
if(a.size()>1) res.P.resize(m-1);
return res;
}
int main()
{
Polygon_convex A;
point a;
vector<point> S;
int t, cs=1;
int n;
double d;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
cin>>d;
S.clear();
For(i,0,n)
{
cin>>a.x>>a.y;
S.push_back(a);
}
A=convex_hull(S);
printf("Case #%d: %.4f\n",cs++,A.calc()/pi/d);
}
return 0;
}