Codeforces Gym - 101635K Blowing Candles [旋转卡壳]
标签:lis oid mes ORC 旋转 max 题意 return 1.0
题意:给你平面上一些点,求一个凸包的最短直径
思路:旋转卡壳,然后搞一下就行了可旋转卡壳求最远点差不多,cur带表的是求出的对锺点,然后与当前的直线p[i],p[i+1],求一下距离
代码:
#include using namespace std;
const double eps = 1e-16;
int sgn(double x)
{
if(fabs(x) return 0;
if(x 0)return -1;
else return 1;
}
struct point
{
double x,y;
point(int _x = 0,int _y = 0)
{
x = _x;
y = _y;
}
point operator -(const point &b)const
{
return point(x - b.x, y - b.y);
}
double operator ^(const point &b)const
{
return x*b.y - y*b.x;
}
double operator *(const point &b)const
{
return x*b.x + y*b.y;
}
void sc()
{
scanf("%lf%lf",&x,&y);
}
};
struct Line
{
point s,e;
Line() {}
Line(point _s,point _e)
{
s = _s;
e = _e;
}
pairint,point> operator &(const Line &b)const
{
point res = s;
if(sgn((s-e)^(b.s-b.e)) == 0)
{
if(sgn((s-b.e)^(b.s-b.e)) == 0)
return make_pair(0,res);
else return make_pair(1,res);
}
double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(2,res);
}
};
double dist(point a,point b)
{
return (double)sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
point NearestpointToLineSeg(point P,Line L)
{
point result;
double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));
if(t >= 0.000 && t 1.0000)
{
result.x = L.s.x + (L.e.x - L.s.x)*t;
result.y = L.s.y + (L.e.y - L.s.y)*t;
}
else
{
if(dist(P,L.s) dist(P,L.e))
result = L.s;
else result = L.e;
}
return result;
}
double emmm(point P,Line L)
{
point zz=NearestpointToLineSeg(P,L);
return dist(zz,P);
}
const int MAXN = 2e5+7;
point List[MAXN];
int Stack[MAXN],top;
bool _cmp(point p1,point p2)
{
double tmp = (p1-List[0])^(p2-List[0]);
if(tmp > 0)return true;
else if(tmp == 0 && dist(p1,List[0]) 0]))
return true;
else return false;
}
void Graham(int n)
{
point p0;
int k = 0;
p0 = List[0];
for(int i = 1; i ){
if(p0.y > List[i].y || (p0.y == List[i].y && p0.x > List[i].x))
{
p0 = List[i];
k = i;
}
}
swap(List[k],List[0]);
sort(List+1,List+n,_cmp);
if(n == 1)
{
top = 1;
Stack[0] = 0;
return;
}
if(n == 2)
{
top = 2;
Stack[0] = 0;
Stack[1] = 1;
return;
}
Stack[0] = 0;
Stack[1] = 1;
top = 2;
for(int i = 2; i )
{
while(top > 1 &&
((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]])) 0)
top--;
Stack[top++] = i;
}
}
double rotating_calipers(point p[],int n)
{
double ans = 999999999999999999999.0;
point v;
int cur = 1;
for(int i = 0; i )
{
v = p[i]-p[(i+1)%n];
while((v^(p[(cur+1)%n]-p[cur])) 0){
cur = (cur+1)%n;s
}
Line qw=Line(p[(i)%n],p[(i+1)%n]);
// point zz=NearestpointToLineSeg(p[cur],qw);
double as=emmm(p[cur],qw);
//as=max(as,zx);
ans=min(ans,as);
// ans=min(ans,max(dist(p[i],p[cur]),dist(p[(i+1)%n],p[(cur+1)%n])));
}
return ans;
}
point p[MAXN];
int main()
{
int n,r;
while(~scanf("%d%d",&n,&r))
{
for(int i = 0; i )List[i].sc();
Graham(n);
for(int i = 0; i List[Stack[i]];
printf("%.16f\n",rotating_calipers(p,top));
}
return 0;
}
Codeforces Gym - 101635K Blowing Candles [旋转卡壳]
标签:lis oid mes ORC 旋转 max 题意 return 1.0
原文地址:https://www.cnblogs.com/lalalatianlalu/p/8973980.html
评论