72分求助
查看原帖
72分求助
210719
Violet___Evergarden楼主2021/12/5 16:22

旋转卡壳

#include <iostream>
#include <algorithm>
#include <cmath>
#define int long long
using namespace std;
const int kMaxN=5e4+1;
struct POINT
{
  int x,y;
}p[kMaxN];
int n;
int sk[kMaxN],cnt;
int ans=-1e15;
int CJ(POINT a,POINT i,POINT j)算叉积
{
  return (i.x-a.x)*(j.y-a.y)-(j.x-a.x)*(i.y-a.y);
}
double Dis(POINT i,POINT j)//算距离
{
  return sqrt((i.x-j.x)*1.0*(i.x-j.x)+(i.y-j.y)*1.0*(i.y-j.y));
}
int Dis2(POINT i,POINT j)//算距离的平方
{
  return (i.x-j.x)*(i.x-j.x)+(i.y-j.y)*(i.y-j.y);
}
bool cmp(POINT i,POINT j)//级角排序
{
  int cj=CJ(p[1],i,j);
  if(cj>0)return true;
  if(cj==0&&Dis(i,p[1])<Dis(j,p[1]))return true;
  return false;
}
signed main()
{
cin>>n;
cin>>p[1].x>>p[1].y;
for(int i=2;i<=n;i++)
{
  cin>>p[i].x>>p[i].y;
  if(p[i].y<p[1].y)
  {
    swap(p[i].x,p[1].x);
    swap(p[i].y,p[1].y);
  }
  else if(p[i].y==p[1].y&&p[i].x<p[1].x)
  {
    swap(p[i].x,p[1].x);
    swap(p[i].y,p[1].y);
  }
}
sort(p+2,p+n+1,cmp);
sk[++cnt]=1;//求凸包
for(int i=2;i<=n;i++)
{
  if(cnt>=2&&CJ(p[sk[cnt-1]],p[sk[cnt]],p[i])<=0)cnt--;
  sk[++cnt]=i;
}
if(cnt==2)
{
  cout<<Dis2(p[sk[1]],p[sk[2]]);
  return 0;
}
sk[++cnt]=1;
int j=3;//旋转卡壳
for(int i=1;i<cnt;i++)
{
  while(CJ(p[sk[i]],p[sk[i+1]],p[sk[j]])<=CJ(p[sk[i]],p[sk[i+1]],p[sk[j+1]]))
  {
    j++;
    if(j==cnt+1)j=1;
  }
  ans=max(ans,max(Dis2(p[sk[i]],p[sk[j]]),Dis2(p[sk[i+1]],p[sk[j]])));
}
cout<<ans;
return 0;
}
2021/12/5 16:22
加载中...