【定义】

【对踵点】多边形上存在平行切线的两点

【多边形半径】多边形上任意两点的最大长度


【旋转卡壳】

选取y轴上,最高和最低的两个点,令两条平行于x轴的线切过这两点

然后我们开始让这两条线旋转

当一条线首先和多边形上一条线段平行时,另外一条边也会停止旋转

这个时候,就需要通过叉乘来判断现在取得对点是否符合要求

即,拥有平行的切线

此处我们用另外一种方法来找到,当前点所对应的最远点(向量的证明还不会QAQ)

确定一条边,然后按逆时针求这个点和这条边组成的三角形的面积

当这个面积最大时,这个点就是最远点

(此处我们找的是,离这条线段最远的点)

需要注意下最初比较选取时,各个值的赋值(我就因为这个浪费了两个小时QAQ)

l max_dis(P* p)
{int maxp = 1, minp = 1;ll  maxy =-1001, miny = 1001;for (int i = 1; i <=n; i++){if (p[i].y > maxy) maxy = p[i].y, maxp = i;if (p[i].y < miny )miny = p[i].y, minp = i;}ll ans = max(dis(p[minp],p[maxp]),dis(p[(minp%n)+1],p[maxp]));for (int i = 1; i <=n; i++,minp=(minp+1>n)?1:(minp+1)){while (cross(p[(minp%n) + 1], p[(maxp % n)+1], p[minp]) > cross(p[(minp%n) + 1], p[maxp], p[minp]))maxp = (maxp+1) %n;ans = max(ans, dis(p[minp], p[maxp]));ans = max(ans, dis(p[(minp % n) +1], p[maxp]));}return ans;
}

View Code


模板题:

【POJ 2178】

给定多边形,求多边形的半径

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#include<map>
#include<cmath>
#define ll int
using namespace std;
const ll eps = 0;
const int MAXN = 50010;
const ll INF = (1<<31)-1;
const ll lim = 100010;
int n;
struct V
{ll x, y;V(ll a = 0, ll b = 0) :x(a), y(b) {}
};
typedef V P;
V    operator+(V a, V b) { return V(a.x + b.x, b.y + a.y); }
V    operator-(V a, V b) { return V(a.x - b.x, b.y - a.y); }
V    operator*(V a, ll b) { return V(a.x*b, a.y*b); }
V    operator*(ll a, V b) { return V(a*b.x, b.y*a); }
V    operator/(V a, ll b) { return V(a.x / b, a.y / b); }
V    operator/(ll a, V b) { return V(b.x / a, b.y / a); }
ll   operator^(V a, V b) { return a.x*b.x + a.y*b.y; }
bool operator<(V a, V b) { return (a.x == b.x) ? a.y < b.y : a.x < b.x; }
int sgn(ll x)
{return (x > eps) - (x < eps);
}
ll  cross(V a, V b)
{return a.x*b.y - b.x*a.y;
}
ll cross(P a, P b, P c)
{return cross(b - a, c - a);
}
ll dis(V a)
{return a ^ a;
}
ll dis(P a, P b)
{return (dis(b - a));
}
P ans[MAXN], s[MAXN];
P p[MAXN];
P* convex(P* l)
{sort(l+1, l+1+n);P tmp(lim, lim);int pos = 0;int top = 0;for (int i = 1; i <=n; i++)if (l[i] < tmp)tmp = l[i], pos = i;for (int i = pos, cnt_ = 0; cnt_ < n; cnt_++, i =(i+1>n)?1:i+1){while (top >= 2 && sgn(cross(s[top-2], s[top-1], l[i])) <= 0)top--;s[top] = l[i]; top++;pos = i;}int cnt = 0;for (int i = 0; i < top; i++){cnt++;ans[cnt] = s[i];}top = 0;for (int i = pos, cnt_ = 0; cnt_ < n; cnt_++, i = (i - 1<1)?n:i-1){while (top >= 2 && sgn(cross(s[top - 2], s[top - 1], l[i])) <= 0)top--;s[top] = l[i]; top++;pos = i;}for (int i = 1; i + 1 < top; i++){cnt++;ans[cnt] = s[i];}n = cnt;return ans;
}
ll max_dis(P* p)
{int maxp = 1, minp = 1;ll  maxy =-1001, miny = 1001;for (int i = 1; i <=n; i++){if (p[i].y > maxy) maxy = p[i].y, maxp = i;if (p[i].y < miny )miny = p[i].y, minp = i;}ll ans = max(dis(p[minp],p[maxp]),dis(p[(minp%n)+1],p[maxp]));for (int i = 1; i <=n; i++,minp=(minp+1>n)?1:(minp+1)){while (cross(p[(minp%n) + 1], p[(maxp % n)+1], p[minp]) > cross(p[(minp%n) + 1], p[maxp], p[minp]))maxp = (maxp+1) %n;ans = max(ans, dis(p[minp], p[maxp]));ans = max(ans, dis(p[(minp % n) +1], p[maxp]));}return ans;
}
int main()
{scanf("%d", &n);for (int i = 1; i <= n; i++){P tmp;scanf("%d%d", &tmp.x, &tmp.y);p[i] = tmp;}printf("%d", max_dis(convex(p)));return 0;
}

View Code

转载于:https://www.cnblogs.com/rentu/p/11272517.html

算法学习:计算几何旋转卡壳相关推荐

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

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

  2. 算法学习——数字旋转方阵

    分析题目 将N*N矩阵分为四个部分,A,B,C,D,对这四个部分依次填充,内层同理 步骤如下:(非递归算法) 定义全局二维数组用于存放矩阵 宏定义一个常量N 编写full()函数用于填充二维数组 对A ...

  3. 计算几何之旋转卡壳算法

    一.目录 一些历史: 1978年, M.I. Shamos's Ph.D. 的论文"Computational Geometry"标志着计算机科学的这一领域的诞生. 当时他发表成果 ...

  4. 旋转卡壳算法(转载)

    https://www.cnblogs.com/little-w/p/3579603.html 转自:http://blog.csdn.net/acmaker/article/details/3188 ...

  5. [模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和

    一些基本的定义在这里: [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算 自适应Simpson Simpson's Rule: \[ \int ^b_a f(x)dx\approx ...

  6. 模板:旋转卡壳(计算几何)

    所谓旋转卡壳,就是旋转起来的卡壳 (逃) 前言 前置知识:凸包 个人感觉很像 two-pointers 算法. 能够在优秀的线性时间复杂度内完成总多求最值(周长.面积-)的神奇操作. 解析 给出情境: ...

  7. 计算几何之 旋转卡壳 代码模板与证明

    旋转卡壳 旋转卡壳这个算法很形象,一般用来在O(nlogn)O(nlogn)O(nlogn)的时间复杂度下求最远点对问题,就是求平面中任意两点的最远距离. 一般求最远点对问题得枚举两个点,所以复杂度是 ...

  8. 旋转卡壳算法求最小外接矩形代码

    旋转卡壳原理:旋转卡壳详解_大学要有梦想的博客-CSDN博客_旋转卡壳 思路: 1.选择卡壳算法用于求凸多边形的最小外接矩形 1.多边形最小的外接矩形一定是以多边形的的一条边为底的一部分 2.通过这条 ...

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

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

最新文章

  1. 解决protobuf import路径的问题
  2. Android Weekly Notes Issue #225
  3. python模块之paramiko学习二
  4. 必填字段的自定义JSF验证器
  5. 产品经理专业知识50篇(五)-用户成长体系设计方案
  6. word break II 对字符串根据已知字典 分解出所有可能组合
  7. 你需要知道的基础算法知识——STL和基础数据结构(二)
  8. Vue学习笔记(五)—— 状态管理Vuex
  9. 惠普应用监控解决方案
  10. WebStrom 使用淘宝镜像
  11. SPSS软件自身案例数据
  12. 【数据攻略】 假设检验 | 统计功效 | 最小样本量
  13. openwrt修改默认网关地址_命令下配置ip地址
  14. Kotlin【简介】Android开发 配置 扩展
  15. 今日快讯: Veeam将以50亿美元被Insight Partners收购兼评SDS之未来
  16. 微软与网景与浏览器之争
  17. 【第一届INT杯】 INT lpy的火柴游戏(大模拟)
  18. 【微信小程序】自定义日志打印
  19. 从头开始实现朴素贝叶斯算法
  20. vins-mono保存、重载地图、evo工具测试

热门文章

  1. Oracle存储过程语法
  2. 2008R2文件服务器迁移到2012R2
  3. Spring注解Annotation
  4. Hyper-V P2V转换遇到的问题
  5. 《Asp.Net 2.0 揭秘》读书笔记(十八)
  6. DNN网站出现服务不可用
  7. ssm整合(基于xml配置方式)
  8. Gogs 0.11.19 发布,自助 Git 托管服务
  9. Tomcat 8熵池阻塞变慢详解
  10. Ajax的用法之JQuery