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

Smallest Bounding Rectangle

Given the Cartesian coordinates of n(>0)2-dimensional points, write a program that computes the area of their smallest bounding rectangle (smallest rectangle containing all the given points).

Input

The input le may contain multiple test cases. Each test case begins with a line containing a positive 
integer n(<1001) indicating the number of points in this test case. Then follows n lines each containing 
two real numbers giving respectively the x - and y 
-coordinates of a point. The input terminates with a 
test case containing a value 0 for n which must not be processed.

Output

For each test case in the input print a line containing the area of the smallest bounding rectangle 
rounded to the 4th digit after the decimal point.

Sample Input


-3.000 5.000 
7.000 9.000 
17.000 5.000 

10.000 10.000 
10.000 20.000 
20.000 20.000 
20.000 10.000 
0

Sample Output

80.0000 
100.0000

给定平面上n个点的坐标,求能够覆盖所有这些点的最小矩形面积。这个问题难就难在,这个矩形可以倾斜放置(边不必平行于坐标轴)。

这里的倾斜放置很不好处理,因为我们不知道这个矩形最终会倾斜多少度。假设我们知道这个矩形的倾角是α,那么答案就很简单了:矩形面积最小时四条边一定都挨着某个点。也就是说,四条边的斜率已经都知道了的话,只需要让这些边从外面不断逼近这个点集直到碰到了某个点。你不必知道这个具体应该怎么实现,只需要理解这可以通过某种方法计算出来,毕竟我们的重点在下面的过程。
我们的算法很显然了:枚举矩形的倾角,对于每一个倾角,我们都能计算出最小的矩形面积,最后取一个最小值。
这个算法是否是正确的呢?我们不能说它是否正确,因为它根本不可能实现。矩形的倾角是一个实数,它有无数种可能,你永远不可能枚举每一种情况。我们说,矩形的倾角是一个“连续的”变量,它是我们无法枚举这个倾角的根本原因。我们需要一种方法,把这个“连续的”变量变成一个一个的值,变成一个“离散的”变量。这个过程也就是所谓的离散化。
我们可以证明,最小面积的矩形不但要求四条边上都有一个点,而且还要求至少一条边上有两个或两个以上的点。试想,如果每条边上都只有一个点,则我们总可以把这个矩形旋转一点使得这个矩形变“松”,从而有余地得到更小的矩形。于是我们发现,矩形的某条边的斜率必然与某两点的连线相同。如果我们计算出了所有过两点的直线的倾角,那么α的取值只有可能是这些倾角或它减去90度后的角(直线按“\”方向倾斜时)这么C(n,2)种。我们说,这个“倾角”已经被我们“离散化”了。虽然这个算法仍然有优化的余地,但此时我们已经达到了本文开头所说的目的。

转载于:https://www.cnblogs.com/BobHuang/p/7198007.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动控制节水灌溉技术的高低代表着农业现代化的发展状况,灌溉系统自动化水平较低是制约我国高效农业发展的主要原因。本文就此问题研究了单片机控制的滴灌节水灌溉系统,该系统可对不同土壤的湿度进行监控,并按照作物对土壤湿度的要求进行适时、适量灌水,其核心是单片机和PC机构成的控制部分,主要对土壤湿度与灌水量之间的关系、灌溉控制技术及设备系统的硬件、软件编程各个部分进行了深入的研究。 单片机控制部分采用上下位机的形式。下位机硬件部分选用AT89C51单片机为核心,主要由土壤湿度传感器,信号处理电路,显示电路,输出控制电路,故障报警电路等组成,软件选用汇编语言编程。上位机选用586型以上PC机,通过MAX232芯片实现同下位机的电平转换功能,上下位机之间通过串行通信方式进行数据的双向传输,软件选用VB高级编程语言以建立友好的人机界面。系统主要具有以下功能:可在PC机提供的人机对话界面上设置作物要求的土壤湿度相关参数;单片机可将土壤湿度传感器检测到的土壤湿度模拟量转换成数字量,显示于LED显示器上,同时单片机可采用串行通信方式将此湿度值传输到PC机上;PC机通过其内设程序计算出所需的灌水量和灌水时间,且显示于界面上,并将有关的灌水信息反馈给单片机,若需灌水,则单片机系统启动鸣音报警,发出灌水信号,并经放大驱动设备,开启电磁阀进行倒计时定时灌水,若不需灌水,即PC机上显示的灌水量和灌水时间均为0,系统不进行灌水。
好的,以下是Graham-Scan算法的C++实现。 ```cpp #include <bits/stdc++.h> using namespace std; struct Point { int x, y; }; // 叉积 int cross(const Point &a, const Point &b, const Point &c) { return (b.x - a.x) * (c.y - b.y) - (b.y - a.y) * (c.x - b.x); } // 求凸包,返回点集 vector<Point> convexHull(vector<Point> &points) { int n = points.size(); // 先按照x坐标从小到大排序,x坐标相同按y坐标从小到大排序 sort(points.begin(), points.end(), [](const Point &a, const Point &b) { return a.x == b.x ? a.y < b.y : a.x < b.x; }); // 求下凸壳 vector<Point> lower; for (int i = 0; i < n; ++i) { while (lower.size() >= 2 && cross(lower[lower.size() - 2], lower.back(), points[i]) <= 0) lower.pop_back(); lower.push_back(points[i]); } // 求上凸壳 vector<Point> upper; for (int i = n - 1; i >= 0; --i) { while (upper.size() >= 2 && cross(upper[upper.size() - 2], upper.back(), points[i]) <= 0) upper.pop_back(); upper.push_back(points[i]); } // 合并下凸壳和上凸壳 vector<Point> ans(lower); ans.insert(ans.end(), upper.begin() + 1, upper.end() - 1); return ans; } int main() { int n; cin >> n; vector<Point> points(n); for (int i = 0; i < n; ++i) cin >> points[i].x >> points[i].y; vector<Point> hull = convexHull(points); cout << "Convex Hull:" << endl; for (const Point &p : hull) cout << p.x << " " << p.y << endl; return 0; } ``` 在上述代码中: - `Point` 结构体表示一个点,包含 `x` 和 `y` 坐标; - `cross` 函数用于计算向量 $\overrightarrow{AB}$ 和 $\overrightarrow{AC}$ 的叉积,即 $(\overrightarrow{AB} \times \overrightarrow{AC})$,结果为正表示 $\overrightarrow{AB}$ 在 $\overrightarrow{AC}$ 的逆时针方向,结果为负表示 $\overrightarrow{AB}$ 在 $\overrightarrow{AC}$ 的顺时针方向,结果为 $0$ 表示 $\overrightarrow{AB}$ 与 $\overrightarrow{AC}$ 共线; - `convexHull` 函数用于求解凸包,输入为点集 `points`,输出为凸包点集; - 在函数内部,先按照 x 坐标从小到大排序,x 坐标相同按 y 坐标从小到大排序; - 接着求下凸壳,利用单调栈维护; - 再求上凸壳,同样利用单调栈维护; - 最后将下凸壳和上凸壳合并,得到最终的凸包点集。 希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值