Rotating card shell summary

Introduction

The basic problem is to find the distance between the two furthest points on a convex polygon, that is, to find the furthest pair of opposite points.

Opposite point: For two points, if two parallel lines can be made through these two points separately, so that all other points on the convex polygon are between these two parallel lines, then these two points are called the opposite heel point.

You can ask for many things if you expand, but the principles are similar.

practice

Simply put, it is to use a pair of parallel lines to clamp the convex hull, and then rotate the convex hull.

There are two situations, one is to jam two points, the other is to jam a point and an edge, like this:
Insert picture description here
consider the situation of jamming an edge and a point, you can find that the stuck point is away from this The side is the farthest, and the triangle formed by this point and this side has the largest area.

Therefore, we have found two pairs of antipodal points (or maybe one), namely the two end points of the edge and the stuck point.

Therefore, for each side, we find the point that forms the largest area of ​​the triangle, which is the point that is stuck.

In this way, it seems to be O (n 2) O(n^2)O ( n2 )The complexity, but here is actually monotonic.

When the polygon rotates clockwise to make the parallel line on the left jam the next side, the point where the red line on the right jammed must be counterclockwise from the point where it was originally stuck.

Therefore, when enumerating the next edge counterclockwise, the point can be found counterclockwise based on the previous time. The time complexity is O (n) O(n)O ( n )

Template question portal

code show as below:

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 50010
#define inf 999999999
#define ll long long

int n,m=0,t=0;
struct point{
    
    
	ll x,y; point(ll xx=0,ll yy=0):x(xx),y(yy){
    
    }
	point operator -(const point &b){
    
    return point(x-b.x,y-b.y);}
	ll operator *(const point &b){
    
    return x*b.y-y*b.x;}
};
point a[maxn],b[maxn],S,zhan[maxn];
ll dis(point x,point y){
    
    return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y);}
bool cmp(point x,point y){
    
    return x*y>0||(x*y==0&&dis(point(0,0),x)<dis(point(0,0),y));}

int main()
{
    
    
	scanf("%d",&n);S.y=inf;
	for(int i=1;i<=n;i++){
    
    
		scanf("%lld %lld",&a[i].x,&a[i].y);
		if(a[i].y<S.y||(a[i].y==S.y&&a[i].x<S.x)){
    
    
			if(S.y!=inf)b[++m]=S;
			S=a[i];
		} else b[++m]=a[i];
	}
	if(m==1){
    
    printf("%lld\n",dis(b[1],S));return 0;}
	for(int i=1;i<=m;i++)b[i].x-=S.x,b[i].y-=S.y;
	sort(b+1,b+m+1,cmp);
	zhan[++t]=point(0,0); zhan[++t]=b[1];
	for(int i=2;i<=m;i++){
    
    
		while(t>1&&(zhan[t]-zhan[t-1])*(b[i]-zhan[t-1])<=0)t--;
		zhan[++t]=b[i];
	}
	int j=2,J=j+1; ll ans=0;
	for(int i=1;i<t;i++){
    
    
		while((zhan[j]-zhan[i+1])*(zhan[i]-zhan[i+1])<(zhan[J]-zhan[i+1])*(zhan[i]-zhan[i+1]))j=J,J=j==t?1:j+1;
		ans=max(ans,max(dis(zhan[j],zhan[i]),dis(zhan[j],zhan[i+1])));
	}
	printf("%lld",ans);
}

Guess you like

Origin blog.csdn.net/a_forever_dream/article/details/106997104