P1452 [USACO03FALL]Beauty Contest G /【模板】旋转卡壳
[USACO03FALL]Beauty Contest G /【模板】旋转卡壳
题目描述
给定平面上
输入格式
第一行一个正整数
接下来
输出格式
输出一行一个整数,表示答案的平方。
样例 #1
样例输入 #1
4
0 0
0 1
1 1
1 0
样例输出 #1
2
提示
【数据范围】
对于
Solution
首先需要知道,平面点集中的最远点对一定是在这个点集的凸包上的(用三角形和延长线去证明),具体证明过程就不写了(我懒)。所以先对这些点跑个 Graham 求凸包,把凸包存储到一个栈
那么该如何在凸包上求这组最远点对呢?想象有两把尺子,将它们摆到一个相互平行的位置,然后将尺子卡到凸包上,这样是不是就卡出来了对于凸包上的某一个点来说的最远点?接着将尺子继续旋转,卡到一个新的边上,这样又得到了新的一个点的最远点。就这样旋转一圈就得到了每个点的最远点,取这些距离值的最大值就是答案。引用一张图来说明就是这样的(这张图应该够形象了):
假设已经知道了一把尺子的位置需要找到另一把尺子,如果直接枚举
那么如何判断当前点是否是最远点呢,这就可以用到向量叉乘的性质了。假设目前尺子卡着的边是
Code
同样是采用结构体表示向量和点,并且重载运算符。
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
template<typename T> void read(T &k)
{
k=0;T flag=1;char b=getchar();
while (!isdigit(b)) {flag=(b=='-')?-1:1;b=getchar();}
while (isdigit(b)) {k=k*10+b-48;b=getchar();}
k*=flag;
}
const int _SIZE=5e4;
struct VEC{
int x,y;
int operator* (const VEC &a) const {return x*a.y-a.x*y;}
VEC operator- (const VEC &a) const {return (VEC){x-a.x,y-a.y};}
}p[_SIZE+5];
int n;
int check(VEC a,VEC b) {return a*b;}
int dis(VEC a,VEC b) {return pow(a.x-b.x,2)+pow(a.y-b.y,2);}
bool cmp(VEC a,VEC b)
{
int temp=check(a-p[1],b-p[1]);
if (temp) return temp>0;
return dis(a,p[1])<dis(b,p[1]);
}
VEC s[_SIZE+5];int cnt=0;
int Calc()
{
if (cnt<4) return dis(s[1],s[2]);
int j=3;int res=0;
for (int i=1;i<cnt;i++)//这里只能到cnt-1不能到cnt,因为当i=cnt时i+1就是一个不存在的点,会导致一些离谱错误
{
res=max(res,dis(s[i],s[i+1]));
while (check(s[i+1]-s[i],s[j]-s[i+1]) <= check(s[i+1]-s[i],s[j%cnt+1]-s[i+1])) j=(j%cnt)+1;
res=max(res,max(dis(s[i],s[j]),dis(s[i+1],s[j])));
}
return res;
}
int main()
{
read(n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
if (p[i].y<p[1].y || (p[i].y==p[1].y && p[i].x<p[1].x)) swap(p[1],p[i]);
}
sort(p+2,p+n+1,cmp);
s[++cnt]=p[1];
for (int i=2;i<=n;i++)
{
while (cnt>1 && check(s[cnt]-s[cnt-1],p[i]-s[cnt])<=0) cnt--;
s[++cnt]=p[i];
}
s[++cnt]=p[1];//这里需要将p[1]加入凸包以方便旋转卡壳的时候可以卡住最后一个点
printf("%d\n",Calc());
return 0;
}
分类:
,
标签:
,
,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步