给n个点,求最远点对,n<=50000

n^2暴力可以过么- -||   给了3s

不过据说凸包+n^2暴力可以过,没有卡数据。

然后我写了一下,发现果然数据很弱。

这是裸的凸包+n^2

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
const int maxn=50000+20;
using namespace std;
struct point
{int x,y;point(){}point(int _x,int _y){x=_x;y=_y;}point operator +(const point&b){return point(x+b.x,y+b.y);}point operator -(const point&b){return point(x-b.x,y-b.y);}point operator *(const int &b){return point(x*b,y*b);}
};
int cross(point a,point b)
{return a.x*b.y-a.y*b.x;
}
int dot(point a,point b)
{return a.x*b.x+a.y*b.y;
}
bool cmp(point a,point b)
{if(a.x!=b.x)return a.x<b.x;return a.y<b.y;
}
int n;
int dis(point a,point b)
{return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
point p[maxn];
point q[maxn];
void solve()
{sort(p+1,p+n+1,cmp);int m=0;for(int i=1;i<=n;i++){while(m>1&&cross(q[m-1]-q[m-2],p[i]-q[m-2])<=0)m--;q[m++]=p[i];}int k=m;for(int i=n-1;i>=1;i--){while(m>k&&cross(q[m-1]-q[m-2],p[i]-q[m-2])<=0)m--;q[m++]=p[i];}int ans=0;for(int i=0;i<m;i++){for(int j=i+1;j<m;j++){ans=max(ans,dis(q[i],q[j]));}}printf("%d\n",ans);
}
int main()
{while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y);solve();}return 0;
}

不过跑的最快的应该就是凸包+旋转卡壳了。

对于一个凸多边形,我们可以尝试用两条相平行但反向的有向直线去夹,一定能够夹住。   夹住的两个点为对踵点。

我们可以看成是对于每一条边,都找到一个最高的点,使得和它构成的三角形面积最大。  然后再转动这个边,如果是逆时针转的,那么新的最高点也会向逆时针转,因为两条平行线转动方向需要一致。利用这个性质我们就可以从上一次找到的点枚举,就降低了复杂度。(一般优化到O(n))

旋转卡壳的代码其实很短:

void qiake(int n)
{int pos=1;int ans=0;for(int i=0;i<n-1;i++){while(cross(q[i+1]-q[i],q[pos]-q[i])<cross(q[i+1]-q[i],q[pos+1]-q[i]))pos=(pos+1)%n;ans=max(ans,dis(q[i],q[pos]));ans=max(ans,dis(q[i+1],q[pos]));}printf("%d\n",ans);
}

看出来了,其实是利用了叉积计算三角形面积,使得某一个点的和边构成的三角形面积最大。

然后就是求最远点对的模版:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
const int maxn=50000+5;
using namespace std;
struct point
{int x,y;point(){}point(int _x,int _y){x=_x;y=_y;}point operator +(const point&b){return point(x+b.x,y+b.y);}point operator -(const point&b){return point(x-b.x,y-b.y);}point operator *(const int &b){return point(x*b,y*b);}
};
int dis(point a,point b)
{return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int cross(point a,point b)
{return a.x*b.y-a.y*b.x;
}
int dot(point a,point b)
{return a.x*b.x+a.y*b.y;
}
bool cmp(point x,point y)
{if(x.x!=y.x)return x.x<y.x;else return x.y<y.y;
}point q[maxn];
point p[maxn];
int len;
void qiake(int n)
{int pos=1;int ans=0;for(int i=0;i<n-1;i++){while(cross(q[i+1]-q[i],q[pos]-q[i])<cross(q[i+1]-q[i],q[pos+1]-q[i]))pos=(pos+1)%n;ans=max(ans,dis(q[i],q[pos]));ans=max(ans,dis(q[i+1],q[pos]));}printf("%d\n",ans);
}
int n;
int solve()
{sort(p+1,p+n+1,cmp);int m=0;for(int i=1;i<=n;i++){while(m>1&&cross(q[m-1]-q[m-2],p[i]-q[m-2])<=0)m--;q[m++]=p[i];}int k=m;for(int i=n-1;i>=1;i--){while(m>k&&cross(q[m-1]-q[m-2],p[i]-q[m-2])<=0)m--;q[m++]=p[i];}if(n>1)m--;return m;
}
point t[maxn];int main()
{while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y);len=solve();qiake(len);}return 0;
}

POJ2187-最远点对-旋转卡壳(怎么开心怎么读)相关推荐

  1. [POJ2187]Beauty Contest(计算几何-旋转卡壳-最远点对)

    题目: 我是超链接 题解: 值得一提的是,这是一个"不定向"算法,为什么呢,因为ta的名字不定哈哈哈,旋转卡壳一共有2*3*2*2=24种不同的读音哦 旋转卡壳可以解决:凸多边形最 ...

  2. POJ - 2187 Beauty Contest (求距离最远点对-凸包+旋转卡壳/枚举 (旋转卡壳学习))

    链接:https://vjudge.net/problem/POJ-2187 题意:求求距离最远点对. 思路:肯定为凸包上的点,可枚举,也可根据凸包性质旋转卡壳求对踵点. 参考博客: https:// ...

  3. POj2187 【模板】旋转卡壳 / 选美大赛

    POj2187 [模板]旋转卡壳 / 选美大赛 题目描述 农夫约翰奖的牛贝西(Bessie)刚刚在牛选美比赛中获得第一名,并获得了"牛世界小姐"的头衔.结果,贝茜将参观世界各地的N ...

  4. 旋转卡壳简介(POJ2187)(洛谷P1452)

    读音 word上是这么读的: 前置技能 凸包 算法用途 旋转卡壳可以在O(n)O(n)O(n)的时间内确定一对对踵点对,它的用途包括但不限于:计算距离(凸多边形直径).计算外接矩形(最小面积/周长). ...

  5. 最远对踵点 旋转卡壳

    original link - http://poj.org/problem?id=2187 题意: 求最远点对 推荐 https://blog.csdn.net/wang_heng199/artic ...

  6. 算法复习——凸包加旋转卡壳(poj2187)

    题目: Description Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest ...

  7. poj 2187 Beauty Contest (凸包: 最远点对,最长直径 , 旋转卡壳法)

    http://poj.org/problem?id=2187 题意: 最长的点对近距离的平方: 题解: 旋转卡壳法, 要注意的地方是,有 所有点共线的情况,所以,(求凸包时)要将,共线点去出 :    ...

  8. BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge Submit: 1435  Solv ...

  9. 算法学习:计算几何旋转卡壳

    [定义] [对踵点]多边形上存在平行切线的两点 [多边形半径]多边形上任意两点的最大长度 [旋转卡壳] 选取y轴上,最高和最低的两个点,令两条平行于x轴的线切过这两点 然后我们开始让这两条线旋转 当一 ...

最新文章

  1. 【旷视研究院】 日常实习生招募—有为青年继续来发光吧
  2. Mac写文件到U盘的方法
  3. 重定向和转发之间的区别
  4. 打包工具的配置教程见的多了,但它们的运行原理你知道吗?
  5. 嵌入式linux h.264,利用ffmpeg来进行视频解码h.264格式(linux)
  6. Git之删除远程分支
  7. datanucleus_DataNucleus 3.0与Hibernate 3.5
  8. REST framework 用户认证源码
  9. asp.net 事件调用事件问题?
  10. 【图像检测-边缘检测】基于PCNN实现图像边缘提取附matlab代码
  11. 思科路由器如何导出配置文件_在思科路由器上保存超大的配置文件
  12. python爬虫豆瓣影评保存到excel_Python爬虫获取豆瓣电影并写入excel
  13. 盘点中国知名网络游戏公司
  14. Lecture 008-Heuristic algorithms
  15. cat3 utp是不是网线_五类, 超五类,六类线,的网线,怎么区分
  16. 【算法】 二叉树遍历
  17. “浙”里别具风采——2018中国软件生态大会·杭州站
  18. 机器人的未来发展的趋势
  19. SQL Server 数据库文件类型
  20. Eclipse中安装Java反编译插件JD-Eclipse

热门文章

  1. Thinkcmf QQ邮箱配置
  2. java面试笔记整理
  3. 【Deep Learning】Transformers Assemble(PART I)
  4. 爬虫-使用代理ip,使用session
  5. 在Windows 记事本中快速选中大量文本的方法
  6. Zeppelin打开定时调度
  7. 微信小程序实现获取当前系统时间
  8. prach---发端
  9. php后端开发主要会哪些技术?
  10. SparkSql 控制输出文件数量且大小均匀(distribute by rand())