2015年百度之星程序设计大赛 - 初赛(1) 1006

比赛链接:2015年百度之星程序设计大赛 - 初赛(1)

题目链接:HDU 5251

Problem Description

小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少。

Input

第一行一个正整数 \(T\),代表测试数据组数 \((1\le T\le 20)\),接下来 \(T\) 组测试数据。

每组测试数据占若干行,第一行一个正整数 \(N(1\le N\le 1000)\),代表矩形的数量。接下来 \(N\) 行,每行 \(8\) 个整数 \(x1,y1,x2,y2,x3,y3,x4,y4\),代表矩形的四个点坐标,坐标绝对值不会超过10000。

Output

对于每组测试数据,输出两行:

第一行输出"Case #i:",i 代表第 i 组测试数据。

第二行包含1 个数字,代表面积最小的矩形的面积,结果保留到整数位。

Sample Input

2
2
5 10 5 8 3 10 3 8
8 8 8 6 7 8 7 6
1
0 0 2 2 2 0 0 2

Sample Output

Case #1:
17
Case #2:
4

Solution

旋转卡壳

思路见这里:洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)

杭电就比较良心了,没有卡精度。

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-8;
const int maxn = 100000 + 5; int n; inline int dcmp(double x) {
if(fabs(x) < eps) return 0;
return x > 0? 1: -1;
} class Point {
public:
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
Point operator+(Point a) {
return Point(a.x + x, a.y + y);
}
Point operator-(Point a) {
return Point(x - a.x, y - a.y);
}
bool operator<(const Point &a) const {
if (x == a.x)
return y < a.y;
return x < a.x;
}
Point operator*(double a) {
return Point(x * a, y * a);
}
bool operator==(const Point &a) const {
if (x == a.x && y == a.y)
return 1;
return 0;
}
double len() {
return sqrt(x * x + y * y);
}
double dis2(const Point a) {
return pow(x - a.x, 2) + pow(y - a.y, 2);
}
double dis(const Point a) {
return sqrt(dis2(a));
}
}; Point ans[10]; typedef Point Vector; double cross(Vector a, Vector b) {
return a.x * b.y - a.y * b.x;
} double dot(Vector a, Vector b) {
return a.x * b.x + a.y * b.y;
} typedef vector<Point> Polygon;
Polygon Andrew(Polygon P) {
int n = P.size(), k = 0;
vector<Point> H(2 * n);
sort(P.begin(), P.end());
for (int i = 0; i < n; ++i) {
while (k >= 2 && cross(H[k - 1] - H[k - 2], P[i] - H[k - 2]) < eps) {
k--;
}
H[k++] = P[i];
}
int t = k + 1;
for (int i = n - 1; i > 0; --i) {
while (k >= t && cross(H[k - 1] - H[k - 2], P[i - 1] - H[k - 2]) < eps) {
k--;
}
H[k++] = P[i - 1];
}
H.resize(k - 1);
return H;
} double rotating_caliper(Polygon v) {
double min_s = 1e18;
int cnt = v.size();
v.push_back(v[0]);
int u = 1, r = 1, l = 1;
for (int i = 0; i < cnt; ++i) {
// 最上面的点
while (dcmp(fabs(cross(v[u] - v[i], v[i + 1] - v[i])) - fabs(cross(v[u + 1] - v[i], v[i + 1] - v[i]))) <= 0) {
u = (u + 1) % cnt;
} // 最右边的点
while (dcmp(dot(v[r] - v[i], v[i + 1] - v[i]) - dot(v[r + 1] - v[i], v[i + 1] - v[i])) <= 0) {
r = (r + 1) % cnt;
} if(!i) l = r; // 最左边的点
while (dcmp(dot(v[l] - v[i], v[i + 1] - v[i]) - dot(v[l + 1] - v[i], v[i + 1] - v[i])) >= 0) {
l = (l + 1) % cnt;
}
double d = v[i].dis(v[i + 1]);
double R = dot(v[r] - v[i], v[i + 1] - v[i]) / d;
double L = dot(v[l] - v[i], v[i + 1] - v[i]) / d;
double ll = R - L;
double dd = fabs(cross(v[u] - v[i], v[i + 1] - v[i])) / d;
min_s = min(min_s, ll * dd);
}
return min_s;
} int main() {
int T;
scanf("%d", &T);
for(int _ = 1; _ <= T; ++_) {
scanf("%d", &n);
Polygon s;
for(int i = 0; i < n * 4; ++i) {
Point p;
scanf("%lf%lf", &p.x, &p.y);
s.push_back(p);
}
Polygon p = Andrew(s);
double d = rotating_caliper(p);
printf("Case #%d:\n%.0lf\n", _, d);
} return 0;
}

HDU 5251 矩形面积 (旋转卡壳)的更多相关文章

  1. HDU 5251 矩形面积(二维凸包旋转卡壳最小矩形覆盖问题) --2015年百度之星程序设计大赛 - 初赛(1)

    题目链接   题意:给出n个矩形,求能覆盖所有矩形的最小的矩形的面积. 题解:对所有点求凸包,然后旋转卡壳,对没一条边求该边的最左最右和最上的三个点. 利用叉积面积求高,利用点积的性质求最左右点和长度 ...

  2. [hdu5251]矩形面积 旋转卡壳求最小矩形覆盖

    旋转卡壳求最小矩形覆盖的模板题. 因为最小矩形必定与凸包的一条边平行,则枚举凸包的边,通过旋转卡壳的思想去找到其他3个点,构成矩形,求出最小面积即可. #include<cstdio> # ...

  3. BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子

    来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...

  4. bzoj1185 [HNOI2007]最小矩形覆盖 旋转卡壳求凸包

    [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 2081  Solved: 920 ...

  5. 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)

    题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...

  6. hdu 最大三角形(凸包+旋转卡壳)

    老师在计算几何这门课上给Eddy布置了一道题目,题目是这样的:给定二维的平面上n个不同的点,要求在这些点里寻找三个点,使他们构成的三角形拥有的面积最大.Eddy对这道题目百思不得其解,想不通用什么方法 ...

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

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

  8. bzoj 1185 [HNOI2007]最小矩形覆盖——旋转卡壳

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1185 矩形一定贴着凸包的一条边.不过只是感觉这样. 枚举一条边,对面的点就是正常的旋转卡壳. ...

  9. 【bzoj1185】[HNOI2007]最小矩形覆盖 (旋转卡壳)

    给你一些点,让你用最小的矩形覆盖这些点 首先有一个结论,矩形的一条边一定在凸包上!!! 枚举凸包上的边 用旋转卡壳在凸包上找矩形另外三点... 注意精度问题 #include<cstdio> ...

随机推荐

  1. git submodule 删除及修改

    1.  删除子模块 # 逆初始化模块,其中{MOD_NAME}为模块目录,执行后可发现模块目录被清空 git submodule deinit {MOD_NAME} # 删除.gitmodules中记 ...

  2. MySQL中的关系

    关系 将实体与实体的关系,反应到最终数据库表的设计中来.将关系分为三种:一对一,一对多(多对一)和多对多.所有的关系都是指的是表与表之间的关系. 一对一 一张表中的一条记录一定只能与另外一张表的一条记 ...

  3. js实现页面跳转的几种方法小结

    地址:https://www.jb51.net/article/84335.htm 地址:https://blog.csdn.net/tsoteo/article/details/77849403

  4. Python判断一个字符串中是否存在多个子串中的一个

    在使用python的开发过程中,常常需要判断,字符串中是否存在子串的问题, 但判断一个字符串中是否存在多个字串中的一个时,如if (a or b) in c或者if x contains a|b|c| ...

  5. Java面试宝典(2)Java基础部分

    31.String s = "Hello";s = s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有? 没有.因为Str ...

  6. CSS2 从入门到精通

    1. 常用的选择器 1. 元素选择器 作用:通过元素选择器可以选择指定的元素 语法:tag{} p{ color: red; } h1{ color: red; } 2. id 选择器 作用:通过元素 ...

  7. live555库得编译、移植、应用

    一.ubuntu下编译 1.生成Makefile文件,编译 ./genMakefiles linux make 2.拷贝liveMedia/include,groupsock/include,Basi ...

  8. strcoll - 用当前的区域选项来比较两个字符串

    总览 (SYNOPSIS) #include <string.h> int strcoll(const char *s1, const char *s2); 描述 (DESCRIPTION ...

  9. KiCAD绘制电源符号

    KiCAD绘制电源符号 KiCAD自带的电源符号有时候不符合我们的操作习惯,需要自己重新定义电源符号,这时候就需要新建(不能更改系统自带库的电源符号) 1.新建符号,参照下图行设置 2.放置引脚和图形 ...

  10. ORA-01000 error

    ORA-01000是最大开放游标错误,是Oracle数据库开发中极为常见的错误. 在Java的上下文中,当应用程序尝试打开更多ResultSet而不是数据库实例上的已配置游标时,会发生这种情况. 解决 ...