POJ - 1113 Wall (凸包模板) Graham Scan 算法实现
Description
Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he would not listen to his Architect's proposals to build a beautiful brick wall with a perfect shape and nice tall towers. Instead, he ordered to build the wall around the whole castle using the least amount of stone and labor, but demanded that the wall should not come closer to the castle than a certain distance. If the King finds that the Architect has used more resources to build the wall than it was absolutely necessary to satisfy those requirements, then the Architect will loose his head. Moreover, he demanded Architect to introduce at once a plan of the wall listing the exact amount of resources that are needed to build the wall.

Your task is to help poor Architect to save his head, by writing a program that will find the minimum possible length of the wall that he could build around the castle to satisfy King's requirements.
The task is somewhat simplified by the fact, that the King's castle has a polygonal shape and is situated on a flat ground. The Architect has already established a Cartesian coordinate system and has precisely measured the coordinates of all castle's vertices in feet.
Input
The first line of the input file contains two integer numbers N and L separated by a space. N (3 <= N <= 1000) is the number of vertices in the King's castle, and L (1 <= L <= 1000) is the minimal number of feet that King allows for the wall to come close to the castle.
Next N lines describe coordinates of castle's vertices in a clockwise order. Each line contains two integer numbers Xi and Yi separated by a space (-10000 <= Xi, Yi <= 10000) that represent the coordinates of ith vertex. All vertices are different and the sides of the castle do not intersect anywhere except for vertices.
Output
Write to the output file the single number that represents the minimal possible length of the wall in feet that could be built around the castle to satisfy King's requirements. You must present the integer number of feet to the King, because the floating numbers are not invented yet. However, you must round the result in such a way, that it is accurate to 8 inches (1 foot is equal to 12 inches), since the King will not tolerate larger error in the estimates.
Sample Input
9 100
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200
Sample Output
1628
Hint
结果四舍五入就可以了
Source
简化下题意即求凸包的周长+2×PI×r。
这道题的答案是凸包周长加上一个圆周长,即包围凸包的一个圆角多边形,但是没弄明白那些圆角加起来为什么恰好是一个圆。每个圆角是以凸包对应的顶点为圆心,给定的L为半径,与相邻两条边的切点之间的一段圆弧。每个圆弧的两条半径夹角与对应的凸包的内角互补。假设凸包有n条边,则所有圆弧角之和为180°n-180°(n-2)=360°。故,围墙周长为=n条平行于凸包的线段+n条圆弧的长度=凸包周长+围墙离城堡距离L为半径的圆周长。
AC代码:学习自KB大佬的模板加以修改
// Author : RioTian
// Time : 20/10/21
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 1000;
const double Pi = acos(-1.0);
struct point {
int x, y;
point() : x(), y() {}
point(int x, int y) : x(x), y(y) {}
} list[N];
typedef point P;
int stack[N], top;
//计算叉积: p0p1 X p0p2
int cross(P p0, P p1, P p2) {
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
//计算 p1p2的 距离
double dis(P p1, P p2) {
return sqrt((double)(p2.x - p1.x) * (p2.x - p1.x) +
(p2.y - p1.y) * (p2.y - p1.y));
}
//利用极角排序,角度相同则距离小排前面
bool cmp(P p1, P p2) {
int tmp = cross(list[0], p1, p2);
if (tmp > 0)
return true;
else if (tmp == 0 && dis(list[0], p1) < dis(list[0], p2))
return true;
else
return false;
}
//输入,并把 最左下方的点放在 list[0] 。并且进行极角排序
void init(int n) {
int i, k = 0;
cin >> list[0].x >> list[0].y;
P p0 = list[0]; // p0 等价于 tmp 去寻找最左下方的点
for (int i = 1; i < n; ++i) {
cin >> list[i].x >> list[i].y;
if (p0.y > list[i].y || (p0.y == list[i].y && p0.x > list[i].x))
p0 = list[i], k = i;
}
list[k] = list[0];
list[0] = p0;
sort(list + 1, list + n, cmp);
}
//graham扫描法求凸包,凸包顶点存在stack栈中
//从栈底到栈顶一次是逆时针方向排列的
//如果要求凸包的一条边有2个以上的点
//那么要将while中的<=改成<
//但这不能将最后一条边上的多个点保留
//因为排序时将距离近的点排在前面
//那么最后一条边上的点仅有距离最远的会被保留,其余的会被出栈
//所以最后一条边需要特判
//如果要求逆凸包的话需要改cmp,graham中的符号即可
void Graham(int n) {
int i;
if (n == 1) top = 0, stack[0] = 0;
if (n == 2) top = 1, stack[0] = 0, stack[1] = 1;
if (n > 2) {
for (i = 0; i <= 1; i++) stack[i] = i;
top = 1;
for (i = 2; i < n; i++) {
while (top > 0 &&
cross(list[stack[top - 1]], list[stack[top]], list[i]) <= 0)
top--;
top++;
stack[top] = i;
}
}
}
int main() {
// freopen("in.txt", "r", stdin);
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int N, L;
while (scanf("%d%d", &N, &L) != EOF) {
init(N);
Graham(N);
//叉积求凸包面积
double res = 0;
for (int i = 0; i < top; i++)
res += dis(list[stack[i]], list[stack[i + 1]]);
res += dis(list[stack[0]], list[stack[top]]);
res += 2 * Pi * L;
printf("%d\n", (int)(res + 0.5));
}
}
POJ - 1113 Wall (凸包模板) Graham Scan 算法实现的更多相关文章
- POJ 1113 Wall 凸包 裸
LINK 题意:给出一个简单几何,问与其边距离长为L的几何图形的周长. 思路:求一个几何图形的最小外接几何,就是求凸包,距离为L相当于再多增加上一个圆的周长(因为只有四个角).看了黑书使用graham ...
- poj 1113 Wall 凸包的应用
题目链接:poj 1113 单调链凸包小结 题解:本题用到的依然是凸包来求,最短的周长,只是多加了一个圆的长度而已,套用模板,就能搞定: AC代码: #include<iostream> ...
- POJ 1113 - Wall 凸包
此题为凸包问题模板题,题目中所给点均为整点,考虑到数据范围问题求norm()时先转换成double了,把norm()那句改成<vector>压栈即可求得凸包. 初次提交被坑得很惨,在GDB ...
- POJ 1113 Wall 凸包求周长
Wall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 26286 Accepted: 8760 Description ...
- poj 1113 wall(凸包裸题)(记住求线段距离的时候是点积,点积是cos)
Wall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 43274 Accepted: 14716 Descriptio ...
- 凸包Graham Scan算法实现
凸包算法实现点集合中搜索凸包顶点的功能,可以处理共线情况,可以输出共线点也可以不输出而只输出凸包顶点.经典的Graham Scan算法,点排序使用极角排序方式,并对共线情况做特殊处理.一般算法是将共线 ...
- 凸包问题 Graham Scan
2020-01-09 15:14:21 凸包问题是计算几何的核心问题,并且凸包问题的研究已经持续了好多年,这中间涌现出了一大批优秀的算法. 凸包问题的最优解法是Graham Scan算法,该算法可以保 ...
- 凸包模板——Graham扫描法
凸包模板--Graham扫描法 First 标签: 数学方法--计算几何 题目:洛谷P2742[模板]二维凸包/[USACO5.1]圈奶牛Fencing the Cows yyb的讲解:https:/ ...
- 计算几何--求凸包模板--Graham算法--poj 1113
Wall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28157 Accepted: 9401 Description ...
- POJ 1113 Wall 求凸包的两种方法
Wall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 31199 Accepted: 10521 Descriptio ...
随机推荐
- Grafana系列-Loki-基于日志实现告警
系列文章 Loki 系列文章 前言 实际应用中除了基于 Metrics 告警, 往往还有基于日志的告警需求, 可以作为基于 Metrics 告警之外的一个补充. 典型如基于 NGINX 日志的错误率告 ...
- C++ Qt开发:CheckBox多选框组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍CheckBo ...
- JUC_start和run
类型: run方法是同步 而start是异步 作用: run方法的作用是存放任务代码 ,start的方法是启动线程 线程数量方面: 执行run方法,他不会产生新线程,而执行start方法hi产生新 ...
- flower插件-监视celery
安装和使用: https://flower.readthedocs.io/en/latest/install.html#installation https://github.com/mher/flo ...
- bash shell笔记整理——ls命令
语法: ls [选项] [文件 或 目录] 选项 使用说明 –a 显示指定目录下的所有文件,包括隐藏文件. -A 显示除了.和..的外的所有文件. -l 显示详细的文件信息. -d 如果是目录,只显示 ...
- Java使用HttpUtil.request方法可以发送请求即【Java访问url得到响应数据】
Java使用HttpUtil.request方法可以发送请求即[Java访问url得到响应数据] 注:这个工具类可以在网上找,也可以自己手写 ,手写的话需要用到以下依赖: <dependency ...
- --{module_name}_binary_host_mirror和--{module_name}_binary_site
--{module_name}_binary_host_mirror和--{module_name}_binary_site demo // .npmrc文件 sass_binary_site=htt ...
- 【GIT-精讲】从零玩转Git-基础理论
关于版本控制 一.什么是版本控制 版本控制(Version Control Systems)版本控制(Revision control)是一种软件工程技巧 在开发的过程中,确保由不同人所编辑的同一档案 ...
- Oracle数据库运维场景下,智能运维如何落地生根?
简介: 「智能运维大数据平台」是一款开箱即用的运维监控平台,通过特有的平台功能可以将企业的基础架构.应用程序.日志管理结合在一起,提供统一采集.统一存储.关联分析.统一监控企业业务保障能力,保障企业业 ...
- 文心一言 VS 讯飞星火 VS chatgpt (177)-- 算法导论13.3 6题
六.用go语言,说明如果红黑树的表示中不提供父指针,应当如何有效地实现 RB-INSERT. 文心一言: 红黑树是一种自平衡的二叉搜索树,其中每个节点都包含一个颜色属性(红色或黑色),并且满足以下性质 ...