\(\color{#0066ff}{题目描述}\)

给定n(>0)二维点的笛卡尔坐标,编写一个程序,计算其最小边界矩形的面积(包含所有给定点的最小矩形)。

输入文件可以包含多个测试样例。每个测试样例从包含一个正数的行开始。 整数N(<1001),表示该测试样例中的点的数量。接下来的n行各包含两个实数,分别给出一个点的x和y坐标。输入最后包含一个值为0的测试样例,该值必须不被处理。

对于输入中的每个测试样例都输出一行,包含最小边界矩形的面积,小数点后四舍五入到第四位。

\(\color{#0066ff}{输入格式}\)

\(\color{#0066ff}{输出格式}\)

\(\color{#0066ff}{输入样例}\)

3
-3.000 5.000
7.000 9.000
17.000 5.000
4
10.000 10.000
10.000 20.000
20.000 20.000
20.000 10.000
0

\(\color{#0066ff}{输出样例}\)

80.0000
100.0000

\(\color{#0066ff}{数据范围与提示}\)

none

\(\color{#0066ff}{题解}\)

旋转卡壳

首先先求一遍凸包

对于最小面积外接矩形,显然至少有一条边与凸包重合,就枚举那条边(底边)

对于上面的边,通过叉积叉出面积判断最高位置,找到上边

对于左边,用点积,找到最大点积(投影最长,那么最靠左),右边指针从左边开始找投影最短

每次移动底边,然后更新上左右,来更新ans

#include <bits/stdc++.h>
#define _ 0
#define LL long long
inline LL in() {
LL x = 0, f = 1; char ch;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
return x * f;
} struct node {
double x,y;
node(double x = 0, double y = 0):x(x), y(y) {}
node operator - (const node &b) const {
return node(x - b.x, y - b.y);
}
double operator ^ (const node &b) const {
return x * b.y - y * b.x;
}
double operator * (const node &b) const {
return x * b.x + y * b.y;
}
double mo() {
return sqrt(x * x + y * y);
}
double jj() const {
return atan2(y, x);
}
};
const int maxn = 10005;
node e[maxn], v[maxn];
int n,top; double S(node a,node b,node c) {
return (b - a) ^ (c - a);
} bool cmp(const node &a, const node &b) {
return (a.jj() < b.jj() || (a.jj() == b.jj() && (a - e[0]).mo() < (b - e[0]).mo()));
}
void tubao() {
int min = 0;
for(int i = 0; i < n; i++)
if(e[i].y < e[min].y || (e[i].y == e[min].y && e[i].x < e[min].x)) min = i;
std::swap(e[0], e[min]);
for(int i = 1; i < n; i++) e[i] = e[i] - e[0];
e[0] = 0;
std::sort(e + 1, e + n, cmp);
v[0] = e[0], v[1] = e[1];
for(int i = top = 2; i < n; i++) {
while((top > 1) && (S(v[top - 2], v[top - 1], e[i]) <= 0)) top--;
v[top++] = e[i];
}
v[top] = e[0];
} double C(node a,node b,node c) {
return (c - a) * (b - a);
} double rotate()
{
if(top < 3) return 0;
int l = 1, u = 1, r;
double a, b, c, ans = 1e20;
for(int i = 0; i < top; i++) {
while(S(v[i], v[i + 1], v[u + 1]) > S(v[i], v[i + 1], v[u])) u = (u + 1) % top;
while(C(v[i], v[i + 1], v[l + 1]) > C(v[i], v[i + 1], v[l])) l = (l + 1) % top;
if(!i) r = l;
while(C(v[i], v[i + 1], v[r + 1]) <= C(v[i], v[i + 1], v[r])) r = (r + 1) % top;
a = S(v[i], v[i + 1], v[u]);
b = C(v[i], v[i + 1], v[l]) - C(v[i], v[i + 1], v[r]);
c = C(v[i], v[i + 1], v[i + 1]);
ans = std::min(ans, a * b / c);
}
return ans;
} int main() {
while("fuck") {
n = in();
if(!n) break;
for(int i = 0; i < n; i++) scanf("%lf%lf", &e[i].x, &e[i].y);
tubao();
printf("%.4lf\n", rotate());
}
return 0;
}

UVA10173 Smallest Bounding Rectangle 最小面积矩形覆盖的更多相关文章

  1. LeetCode 939. Minimum Area Rectangle (最小面积矩形)

    题目标签:HashMap 题目给了我们一组 xy 上的点坐标,让我们找出 能组成矩形里最小面积的那个. 首先遍历所有的点,把x 坐标当作key 存入map, 把重复的y坐标 组成set,当作value ...

  2. Smallest Bounding Rectangle - uva10173

    Smallest Bounding Rectangle Given the Cartesian coordinates of n(>0)2-dimensional points, write a ...

  3. 此坑待填 离散化思想和凸包 UVA - 10173 Smallest Bounding Rectangle

    Smallest Bounding Rectangle Given the Cartesian coordinates of n(>0)2-dimensional points, write a ...

  4. LeetCode939 最小面积矩形

    LeetCode939最小面积矩形 给定在 xy 平面上的一组点,确定由这些点组成的矩形的最小面积,其中矩形的边平行于 x 轴和 y 轴. 如果没有任何矩形,就返回 0. Input [[1,1],[ ...

  5. [Swift]LeetCode939. 最小面积矩形 | Minimum Area Rectangle

    Given a set of points in the xy-plane, determine the minimum area of a rectangle formed from these p ...

  6. [Swift]LeetCode963. 最小面积矩形 II | Minimum Area Rectangle II

    Given a set of points in the xy-plane, determine the minimum area of any rectangle formed from these ...

  7. Leetcode963. Minimum Area Rectangle II最小面积矩形2

    给定在 xy 平面上的一组点,确定由这些点组成的任何矩形的最小面积,其中矩形的边不一定平行于 x 轴和 y 轴. 如果没有任何矩形,就返回 0. 示例 1: 输入:[[1,2],[2,1],[1,0] ...

  8. bzoj 1185 旋转卡壳 最小矩形覆盖

    题目大意 就是求一个最小矩形覆盖,逆时针输出其上面的点 这里可以看出,那个最小的矩形覆盖必然有一条边经过其中凸包上的两个点,另外三条边必然至少经过其中一个点,而这样的每一个点逆时针走一遍都满足单调性 ...

  9. hdu5251最小矩形覆盖

    题意(中问题直接粘吧)矩形面积 Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少.   Input ...

随机推荐

  1. javascript——对象的概念——函数 2 (内建函数与类型转换)

    javascript 有许多内建函数,用于各种操作,以下为常用的内建方法. 1.parseInt(object,int):将输入的 int 进制的值 object 转换为 10 进制的数值: obje ...

  2. DDD学习笔录——简介DDD的战术模式、问题空间和解空间

    DDD的战术模式 DDD的战术模式(也称为模型构造块)是一个帮助创建 用于复杂有界上下文的有效模型的 模式集合. 也就是我们常说的设计模式. 问题空间 问题空间将问题域提炼成更多可管理的子域,是真对于 ...

  3. When install ”matplotlib” with ”pip”, if you get the following error, it means the “freetype” and “png” libraries needed by matplotlib are not installed:

    ============================================================================ * The following require ...

  4. js正则基础总结和工作中常用验证规则

    知识是需要系统的.就像js正则用了那么多次,却还是浑浑噩噩,迫切需要来一次整理,那么来吧! 基本知识 元字符 \d 匹配数字等于[0-9] \w 匹配字母.数字.下划线.中文 \s 匹配任意空白字符 ...

  5. opencv 美白磨皮人脸检测<转>

    1. 简介 这学期的计算机视觉课,我们组的课程项目为“照片自动美化”,其中我负责的模块为人脸检测与自动磨皮.功能为:用户上传一张照片,自动检测并定位出照片中的人脸,将照片中所有的人脸进行“磨皮”处理, ...

  6. adb eclipse 截屏

    DDMS  左侧  选中设备 右上角有一个相机样式的按钮"screen capture"

  7. 修改oracle xe的8080端口

    1.用sys管理员身份登录,利用dbms_xdb修改端口设置 SQL> -- Change the HTTP/WEBDAV port from 8080 to 8081 SQL> call ...

  8. JavaScript去除空格的三种方法(正则/传参函数/trim)

    方法一: 个人认为最好的方法.采用的是正则表达式,这是最核心的原理. 其次.这个方法使用了JavaScript 的prototype 属性 其实你不使用这个属性一样可以用函数实现.但这样做后用起来比较 ...

  9. 用position: sticky 实现粘性元素区域悬浮效果(转)

    用position: sticky 实现粘性元素区域悬浮效果 原创 2017年08月02日 20:04:13 161 在一些很长的表格中,常常会使用表头悬浮的设计以方便阅读,即在表格离开窗口之前,表头 ...

  10. socket多线程方式案例

    记下来,方便以后查看 User类 package com.xujingyang.ThreadSocket; import java.io.Serializable; public class User ...