题意:给出点集,求覆盖所有点的最小面积矩形和最小周长矩形。

参考了很多Killerfear前辈的代码:传送门。

枚举每条边为矩形底边,找出最高点和最左最右点。

判断最高点是三角形面积,最左最右点是点积的正负。

最左最右点各占据凸包一半的点。

可以推出这三个点的性质都是单峰函数。

#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
#define MAXN 100010
#define eps 1e-10//const double pi = acos(-1.0);
inline double sig(double x) { return (x > eps) - (x < -eps); };typedef struct Point
{double x, y;Point() {}Point(double _x, double _y):x(_x), y(_y) {}bool operator <(const Point &argu) const { return sig(x - argu.x) == 0 ? y < argu.y : x < argu.x; }double dis(const Point &argu) const { return sqrt((x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y)); }double dis2(const Point &argu) const { return (x - argu.x) * (x - argu.x) + (y - argu.y) * (y - argu.y); }double operator ^(const Point &argu) const { return x * argu.y - y * argu.x; }double operator *(const Point &argu) const { return x * argu.x + y * argu.y; }Point operator -(const Point &argu) const { return Point(x - argu.x, y - argu.y); }double len2() const { return x * x + y * y; }double len() const { return sqrt(x * x + y * y); }void in() { scanf("%lf%lf", &x, &y); }void out() { printf("%.3lf %.3lf\n", x, y); }
}Vector;inline double Cross(const Point &o, const Point &a, const Point &b) { return (a - o) ^ (b - o); }int ConvexHull(Point p[], Point ch[], int n)
{sort(p, p + n);int top = 0;for(int i = 0; i < n; i++){while(top > 1 && Cross(ch[top - 2], ch[top - 1], p[i]) <= 0) top--;ch[top++] = p[i];}int t = top;for(int i = n - 2; i >= 0; i--){while(top > t && Cross(ch[top - 2], ch[top - 1], p[i]) <= 0) top--;ch[top++] = p[i];}top--;return top;
}void RotatingCalipers(Point p[], int n, double &mina, double &minp)
{int t = 1, l = 1, r = 1;mina = minp = 1e15;for(int i = 0; i < n; i++){//枚举边(p[i], p[i+1])while(sig((p[i + 1] - p[i]) ^ (p[t + 1] - p[t])) > 0) t = (t + 1) % n; //找出最高点while(sig((p[i + 1] - p[i]) * (p[r + 1] - p[r])) > 0) r = (r + 1) % n; //找出最右点if(i == 0) l = (r + 1) % n; //初始化最左点while(sig((p[i + 1] - p[i]) * (p[l + 1] - p[l])) < 0) l = (l + 1) % n; //找出最左点double d = p[i + 1].dis(p[i]);double h = ((p[i + 1] - p[i]) ^ (p[t] - p[i])) / d; //三角形高double w = ((p[i + 1] - p[i]) * (p[r] - p[l])) / d; //投影mina = min(mina, h * w);minp = min(minp, 2 * (h + w));}
}Point pp[MAXN], ch[MAXN];
int n, c;
double mina, minp;void solve()
{c = ConvexHull(pp, ch, n); ch[c] = ch[0];RotatingCalipers(ch, c, mina, minp);printf("%.2lf %.2lf\n", mina, minp);
}int main()
{
//    freopen("12307.in", "r", stdin);while(scanf("%d", &n) && n){for(int i = 0; i < n; i++) pp[i].in();solve();}return 0;
}

UVa 12307 Smallest Enclosing Rectangle(旋转卡壳+最小覆盖矩形)相关推荐

  1. 6 最小覆盖矩形(Smallest Rectangle Enclosing Black Pixels)

    文章目录 1 题目 2 描述 3 思路 3.1 图解 3.2 时间复杂度 3.3 空间复杂度 4 源码 1 题目   最小覆盖矩形(Smallest Rectangle Enclosing Black ...

  2. CF1578F Framing Pictures 旋转卡壳+积分

    CF1578F Framing Pictures 旋转卡壳+积分 Framing Pictures 题目描述 Life has been discovered on Venus! What is mo ...

  3. 旋转卡壳凸包(不用一下子就学完所有)

    目录 前言 参考博客 前置知识 1.极角排序 2.凸包(默认逆时针) 3.对踵点 旋转卡壳能解决的各类问题 1.计算距离 1.1凸多边形直径 1.2凸多边形宽 1.3凸多边形间最大距离 1.4凸多边形 ...

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

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

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

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

  6. Bridge Across Islands POJ - 3608 旋转卡壳求凸包最近距离

    \(\color{#0066ff}{题目描述}\) 几千年前,有一个小王国位于太平洋的中部.王国的领土由两个分离的岛屿组成.由于洋流的冲击,两个岛屿的形状都变成了凸多边形.王国的国王想建立一座桥来连接 ...

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

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

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

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

  9. bzoj 1069 [SCOI2007]最大土地面积——旋转卡壳

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1069 发现 n 可以 n^2 .所以枚举对角线,分开的两部分三角形就可以旋转卡壳了. 注意坐 ...

  10. 【BZOJ1185】【HNOI2007】最小矩形覆盖(凸包+旋转卡壳)

    传送门 题意:求最小矩阵覆盖 有这样一个结论:矩阵一定有一条边在凸包上(不会证) 那可以枚举每条边 同时旋转卡壳 只是这时不只维护一个对踵点对,同时在左右侧再维护一个最远点 可以发现左右最远点一定是和 ...

最新文章

  1. 跨平台C++开源码的两种经常使用编译方式
  2. CNCF宣布Envoy项目正式毕业
  3. HTC G7 金卡 制作
  4. 易语言 字段重复_使对易失性字段的操作原子化
  5. C++primer拾遗(第八章:IO库)
  6. 去年出货的工业机器人,超过1/3都跑来了中国
  7. PX4日志读取并转化为.scv文件、MATLAB显示
  8. SQLExpress免费版配置本地数据库实例
  9. matlab中图例的字怎么改,如何在Matlab图形图例中设置自定义标记
  10. Ubuntu服务器用户磁盘空间quota分配
  11. 如何通过织云 Lite 愉快地玩转 TSW
  12. 织梦后台登录后页面一片空白怎么办?
  13. 限时删,2020 CSDN 博客之星排名泄露
  14. 什么软件能测试电脑能不能玩lol,怎么判断自己的电脑能不能玩lol_电脑配置检测的方法 - 驱动管家...
  15. CMD下添加IP地址,删除IP地址
  16. 玖月:如果真的能够穿越回到过去,我可能只会给自己一个微笑
  17. 正大国际期货:外盘期货中几种买入卖出价有何区别?
  18. ResNet论文翻译——中英文对照+标注总结
  19. 【Python】随机漫步
  20. 凤凰工作室秘密档案 The world 浏览器团队访谈

热门文章

  1. 使用 Envoy 和 AdGuard Home 阻挡烦人的广告
  2. python爬虫字体反爬实习僧
  3. 3.9 Primitive Obsession 基本类型偏执
  4. php sendmail 抄送,Python发送邮件各种姿势
  5. TIC TAC TOE 井字游戏
  6. 用Hadoop构建电影推荐系统
  7. 台式计算机技术参数响应表,详细技术参数响应表介绍.doc
  8. OC 实现扫雷达扫描动画
  9. js下载文件格式为Excel后提示与文件扩展名不一致,打开文件前请验证文件没有损坏且来源可信.
  10. 数据库原理及安全技术教学实验报告SQL实践(一)