POJ 2187 计算几何之旋转卡壳
来源:互联网 发布:red flag linux 8.0 编辑:程序博客网 时间:2024/06/10 18:01
首先这个题目可以用先求凸包再暴力枚举的方法通过,原因不是数据出水了,而是因为有一个奇葩的结论就是坐标值不超过K的不同的多边形最多不会超过 sqrt (K) 个 所以求出凸包后暴力枚举时间复杂度是可以接受的
- 关于多边形的切线 : 就是说一条直线与多边形相交,并且多边形在直线的一侧,这样的直线称之为多边形的切线,
关于多边形的对踵点 : 多边形的对踵点就是 : 两条平行的多边形切线上的与多边形相交的点。 对踵点有三种情况
- 两条切线都只与多边形有一个交点
- 两条切线都与多边形有无数多个交点
- 一个有一个交点,另一个有无穷多个交点
关于旋转卡壳 : 是一种求平面上所有点的最远对点的算法,我们知道可以通过求凸包 + 枚举凸包上的点的方式求出平面上所有点的最远距离,但是这种方法在凸包上的点过多的时候时间复杂度退化到 O (n ^ 2) 对于有些题目是不可以接受的,这个时候就要采取旋转卡壳的方法求平面上任意两个点的最远距离。(也叫做多边形的直径) 因为可以保证对踵点的个数不会超过 3/2n 个 所以算法的时间复杂度可以保证
- 具体实现
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;const int maxn = 50005;const double eps = 1e-8;const int INF = 1e9 + 7;struct point { int x,y;}p[maxn];point poly[maxn] = {0};point init;int n;int tot;int ab (int x) {return x > 0 ? x : -x;}int dist (point a,point b) { return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);}int cross (int x1,int y1,int x2,int y2) { return x1 * y2 - x2 * y1;}bool cmp (const point a,const point b) { if (cross(a.x - init.x,a.y - init.y,b.x - init.x,b.y - init.y) != 0) { return cross(a.x - init.x,a.y - init.y,b.x - init.x,b.y - init.y) > 0; } else { return dist (a,init) < dist (b,init); }}void tubao () { for (int i = 1;i <= 2; ++ i) poly[i] = p[i]; tot = 2; for (int i = 3;i <= n; ++ i) { while (tot >= 2) { point p1,p2,p3; p1 = poly[tot]; p2 = poly[tot - 1]; p3 = p[i]; if (cross (p1.x - p2.x,p1.y - p2.y,p3.x - p1.x,p3.y - p1.y) <= 0) tot --; else break; } poly[++ tot] = p[i]; }}int rotating () { if (tot == 2) return dist (poly[1],poly[2]); poly[++tot] = poly[1]; int ans = 0; int u = 2; for (int i = 1;i < tot; ++ i) { int mxd = max (dist (poly[u],poly[i]),dist (p[u],poly[i + 1])); ans = max (ans,mxd); while (ab (cross(poly[i].x - poly[u].x, poly[i].y - poly[u].y, poly[i + 1].x - poly[u].x, poly[i + 1].y - poly[u].y)) <= ab (cross(poly[i].x - poly[u + 1].x, poly[i].y - poly[u + 1].y, poly[i + 1].x - poly[u + 1].x, poly[i + 1].y - poly[u + 1].y))) { u = u % tot + 1; mxd = max (dist (poly[u],poly[i]),dist (p[u],poly[i + 1])); ans = max (ans,mxd); } } return ans;}int main () { ios_base :: sync_with_stdio(false); while (cin >> n) { for (int i = 1;i <= n; ++ i) { cin >> p[i].x >> p[i].y; if (p[i].y < p[1].y) { swap (p[1],p[i]); } else if (p[i].y == p[1].y && p[i].x < p[1].x) { swap (p[1],p[i]); } } if (n == 2) { cout << dist (p[1],p[2]) << endl; continue; } init = p[1]; sort (p + 1,p + n + 1,cmp); tubao(); cout << rotating() << endl; } return 0;}
阅读全文
0 0
- POJ 2187 计算几何之旋转卡壳
- POJ 2187(计算几何+旋转卡壳法或暴力)
- 【转载】[Poj 2187]计算几何之凸包(三) {旋转卡壳初步}
- 计算几何学习笔记之旋转卡壳
- 计算几何之旋转卡壳算法
- POJ 2079(计算几何+凸包+旋转卡壳法)
- poj 2187 Beauty Contest 计算几何(凸包+旋转卡壳法)/最远点对
- 计算几何之凸包(三) {旋转卡壳初步}
- [计算几何笔记2]旋转卡壳
- 计算几何——旋转卡壳【POJ2187】
- 计算几何——旋转卡壳
- POJ-2187(旋转卡壳)
- 计算几何之二维凸包:卷包裹算法、Graham Scan Algorithm、旋转卡壳算法
- poj 2187(旋转卡壳)
- poj 2187(旋转卡壳)
- 【计算几何】 Andrew凸包算法 + 旋转卡壳(以求点对最长距离为例) -- 以 POJ 2187 Beauty Contest 为例
- bzoj1069: [SCOI2007]最大土地面积 计算几何 旋转卡壳
- bzoj1185: [HNOI2007]最小矩形覆盖 计算几何 旋转卡壳
- Greendao.gen使用方法总结
- [bzoj1293][SCOI2009]生日礼物(莫队)
- html基础教程-doctype
- JAVA多态
- Myeclipse如何导出doc文档
- POJ 2187 计算几何之旋转卡壳
- 使用studio将module打包成jar包
- MongoDB学习(一)MongoDB常用命令
- Java获取视频时长、宽高、文件大小、格式、并截图做封面
- Redis数据结构详解之Zset
- 浅谈UI设计师的职业发展
- Spark Streaming(下)--实时流计算Spark Streaming实战
- 装饰者设计模式 -C#
- Simple Selection Sort(简单选择排序)