luogu P2742 【模板】二维凸包
嘟嘟嘟
没错,我开始学凸包了。
其实挺简单的。
前置技能:
1.极坐标系
2.向量叉积
1.极坐标系
就是一种二维坐标系。只不过两个坐标分别表示向量和极轴的角度和自身的长度。对于不同的问题,极轴可以自己选取。
2.向量叉积
不说了
算法是\(Graham\)扫描法,下面讲一下实现步骤:
1.在所有点中找到横坐标最小的点作为极点,如果有多个,取纵坐标最小的点。
2.对于其他\(n -1\)个点进行极角排序,极角相同比较到极点距离。
排完序后的图大概是这个样子的:

其中的字母就是排完序后的序号。
3.然后维护一个栈,对于每一个点,比较他和栈顶的两个点构成的线段,如果在线段的右边,就把栈顶弹出,直到栈中只剩一个元素或该点在线段右边为止。
4.最后栈中的元素就是凸包的顶点。
再补充几点:
1.极角排序的函数怎么写。
对于极点\(A\)和要排序的两个点\(B, C\)。就是看\(C\)在\(AB\)的上方还是下方。这个用叉积判断即可。如果\(\overrightarrow{AB} \times \overrightarrow{AC} < 0\),说明\(C\)在\(AB\)下方,反之亦然。
如果叉积等于\(0\),比较到\(A\)点距离。
2.判断点\(i\)在栈顶两个元素所成直线的左右。
跟上面一样,叉积。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e4 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n;
struct Vec
{
db x, y;
db operator * (const Vec& oth)const
{
return x * oth.y - oth.x * y;
}
friend inline db dis(const Vec& A)
{
return A.x * A.x + A.y * A.y;
}
};
struct Point
{
db x, y;
int id;
Vec operator - (const Point& oth)const
{
return (Vec){x - oth.x, y - oth.y};
}
friend void swap(Point& A, Point& B)
{
swap(A.x, B.x); swap(A.y, B.y);
}
}p[maxn], S;
inline bool cmp(Point A, Point B)
{
db s = (A - S) * (B - S);
if(fabs(s) > eps) return s > eps;
return dis(A - S) - dis(B - S) < -eps;
}
db solve(Point A, Point B, Point C)
{
return (B - A) * (C - A);
}
void init()
{
int id = 1;
for(int i = 2; i <= n; ++i)
if(p[i].x < p[id].x - eps || (fabs(p[i].x - p[id].x) < eps && p[i].y < p[id].y)) id = i;
if(id != 1) swap(p[1], p[id]);
S.x = p[1].x; S.y = p[1].y;
for(int i = 1; i <= n; ++i) p[i].id = i;
sort(p + 2, p + n + 1, cmp);
}
int st[maxn], top = 0;
db ans = 0;
int main()
{
n = read();
for(int i = 1; i <= n; ++i) scanf("%lf%lf", &p[i].x, &p[i].y);
init();
st[++top] = 1;
for(int i = 2; i <= n; ++i)
{
while(top > 1 && solve(p[st[top - 1]], p[st[top]], p[i]) < -eps) top--;
st[++top] = i;
}
st[top + 1] = st[1];
for(int i = 1; i <= top; ++i)
ans += sqrt(dis(p[st[i + 1]] - p[st[i]]));
printf("%.2lf\n", ans);
return 0;
}
然后我因为极点没赋初值\(Debug\)了不知多长时间……
luogu P2742 【模板】二维凸包的更多相关文章
- Luogu P2742 模板-二维凸包
Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...
- luogu P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows
题解: 二维凸包裸题 按照x坐标为第一关键字,y坐标为第二关键字排序 然后相邻判断叉积用单调队列搞过去 正反都做一次就好了 代码: #include <bits/stdc++.h> usi ...
- 【洛谷 P2742】【模板】二维凸包
题目链接 二维凸包板子..有时间会补总结的. #include <cstdio> #include <cmath> #include <algorithm> usi ...
- 【计算几何】二维凸包——Graham's Scan法
凸包 点集Q的凸包(convex hull)是指一个最小凸多边形,满足Q中的点或者在多边形边上或者在其内.右图中由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包. 一组平面上的点, ...
- UVA 10652 Board Wrapping(二维凸包)
传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组 ...
- 计算几何 二维凸包问题 Andrew算法
凸包:把给定点包围在内部的.面积最小的凸多边形. Andrew算法是Graham算法的变种,速度更快稳定性也更好. 首先把全部点排序.依照第一keywordx第二keywordy从小到大排序,删除反复 ...
- 使用Graham扫描法求二维凸包的一个程序
#include <iostream> #include <cstring> #include <cstdlib> #include <cmath> # ...
- poj 2079 Triangle (二维凸包旋转卡壳)
Triangle Time Limit: 3000MS Memory Limit: 30000KB 64bit IO Format: %I64d & %I64u Submit Stat ...
- poj 2187 Beauty Contest(二维凸包旋转卡壳)
D - Beauty Contest Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u ...
随机推荐
- zabbix自动发现与自动注册及SNMP监控
自动发现与自动注册 自动发现:zabbix Server主动发现所有客户端,然后将客户端登记自己的小本本上,缺点zabbix server压力山大(网段大,客户端多),时间消耗多. 自动注册:zabb ...
- WPF判断两个时间大小避免误差
进行查询操作的时候,经常用到判断开始时间和结束时间大小的条件,由于从控件上获取的时间除了年月日时分秒,还包括毫秒.微秒等,导致直接判断时间大小的时候会产生一些误差,如下: 结果分析:年月日时分秒一致的 ...
- oracle锁表问题解决
select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session s where l ...
- Java新人拿到一台新的电脑需要装配什么
适用对象:新手 装备:win10 一.IDEA 插件等 说明 其他 TranslationPlugin 翻译插件 GitHub地址 MyBatis-Generator 自动生成Mybatis文件 Al ...
- apache-kylin 权威指南—读书笔记
1. 概述 kylin 是 OLAP 引擎,采用多维立方体预计算技术,可将大数据的 SQL 查询速度提升到亚秒级别. 需求: 虽然像 spark,hive 等使用 MPP 大规模并行处理和列式存储的方 ...
- ES6学习笔记(二)-字符串的扩展
一.字符的 Unicode 表示法 JavaScript 允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点. 表示法只限于码点在\u0000~\uFFFF之间的字符, ...
- PHP在foreach中对$value赋值无效,应该用 ‘键’ 或者 &$value的形式
首先我们看下这段代码: foreach ($data as$value) { $value['name'] = 'Hehe'; } $data中原始的数据为: array(1) { [0] => ...
- Vue.js小案例(1)
数据绑定 数据绑定是vue.js的基础.本例中就是利用了vue.js的v-model指令在表单元素上创建双向数据绑定. <!--这是我们的View--> <div id=" ...
- springmvc和spring的区别
springmvc只是spring其中的一部分.spring 可以 支持 hibernate ,ibatis ,JMS,JDBC 支持事务管理, 注解功能,表达式语言,测试springmvc 就是一个 ...
- Redis的基本操作语句
注:以下出现的key.value都需要具体 1.String类型的数据存储获取 set key value:设置key的值为value,若存在则覆盖,不存在则自动创建decrby get key:获取 ...