当前位置: 首页 > news >正文

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

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

参考了很多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;
}



http://www.taodudu.cc/news/show-2639128.html

相关文章:

  • 【physx/wasm】在physx中添加自定义接口并重新编译wasm
  • excel---常用操作
  • Lora训练Windows[笔记]
  • linux基础指令讲解(ls、pwd、cd、touch、mkdir)
  • InnoDB 事务处理机制
  • 启明云端ESP32 C3 模组WT32C3通过 MQTT 连接 AWS
  • uva 12307(点集的外接矩形)
  • UVA 12307 Smallest Enclosing Rectangle(旋转卡壳)
  • uva 12307 - Smallest Enclosing Rectangle(旋转卡壳)
  • UVA 12307 Smallest Enclosing Rectangle
  • UVA 12307 旋转卡壳
  • uva12307(旋转卡壳)
  • UVA12307 Smallest Enclosing Rectangle 题解
  • numpy.ptp
  • gPTP与PTP理解资料参考
  • linux下ptp性能测试
  • 时统ptp_IEEE1588 PTP对时系统原理及特点
  • 时统ptp_IEEE1588对时系统,PTP校时模块,PTP时钟服务器
  • linuxptp源码研究
  • ptp输出内容包含什么_PTP技术及其应用分析
  • IEEE1588 Precision Time Protocol(PTP)
  • Linuxptp安装部署
  • Ubuntu 设置PTP时间同步
  • PTP时间同步
  • ptp4l linux,如何使用PTP4l测试PTPV2协议精度?
  • android ptp 源码分析,ptp增加豆瓣评分
  • PTP移植
  • linuxptp分析
  • ptp输出内容包含什么_PTP 无线传输
  • ptp精准时间协议_精确时间协议PTP研究
  • ptp精准时间协议_PTP时钟协议原理
  • ptp输出内容包含什么_04-PTP命令
  • 详解PTP协议
  • ptp输出内容包含什么_解剖PTP协议
  • Genero Studio导入ds.sch失败处理办法_Error importing schema file:Check Ouput view for datails. mod-db3[11003]
  • 利用JAVA的BFS爬虫爬出豆瓣读书的评论和标签