[bzoj1007]:[HNOI2008]水平可见直线(单调栈)

2024-02-05 15:08

本文主要是介绍[bzoj1007]:[HNOI2008]水平可见直线(单调栈),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传送门
姑且算是计算几何第一题吧。。
首先,最后的图形一定是一个凸包形状的东西。
所以,我们按照k递增为第一关键字,b递减为第二关键字,排个序。
然后我们就可以维护一个单调栈,处理结果了。
方法:
我们设当前直线与栈顶直线的交点为x1,栈顶直线与栈顶第二条直线的交点为x2
如果x1<=x2,那么弹出栈顶;否则将当前直线压入栈中。
原理可以看这个图,直到看懂为止。
这里写图片描述
懂了的话,那就没什么了。
对了,目前洛谷Rank1
代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
inline int read(){int x=0;char ch=' ';int f=1;while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();if(ch=='-')f=-1,ch=getchar();while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return x*f;
}
const int N=5e5+5;
const double eps=1e-8;
struct line{double k,b;int id;inline bool operator < (const line& y) const {if(fabs(k-y.k)<eps)return b>y.b;return k<y.k;}
}a[N];
int n,top,vis[N],s[N];
inline double calc(const line& a,const line& b){return (b.b-a.b)/(a.k-b.k);
}
int main(){n=read();for(int i=1;i<=n;i++)scanf("%lf %lf",&a[i].k,&a[i].b),a[i].id=i;sort(a+1,a+n+1);top=1;s[1]=1;for(int i=2;i<=n;i++){if(fabs(a[i].k-a[i-1].k)<eps)continue;while(top>1&&calc(a[i],a[s[top]])<=calc(a[s[top]],a[s[top-1]])+eps)top--;s[++top]=i;}for(int i=1;i<=top;i++)vis[a[s[i]].id]=1;for(int i=1;i<=n;i++)if(vis[i])printf("%d ",i);return 0;
}

这篇关于[bzoj1007]:[HNOI2008]水平可见直线(单调栈)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/681297

相关文章

POJ1269 判断2条直线的位置关系

题目大意:给两个点能够确定一条直线,题目给出两条直线(由4个点确定),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。 解题思路: 先判断两条直线p1p2, q1q2是否共线, 如果不是,再判断 直线 是否平行, 如果还不是, 则两直线相交。  判断共线:  p1p2q1 共线 且 p1p2q2 共线 ,共线用叉乘为 0  来判断,  判断 平行:  p1p

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

求空间直线与平面的交点

若直线不与平面平行,将存在交点。如下图所示,已知直线L过点m(m1,m2,m3),且方向向量为VL(v1,v2,v3),平面P过点n(n1,n2,n3),且法线方向向量为VP(vp1,vp2,vp3),求得直线与平面的交点O的坐标(x,y,z): 将直线方程写成参数方程形式,即有: x = m1+ v1 * t y = m2+ v2 * t

力扣 739. 每日温度【经典单调栈题目】

1. 题目 理解题意: 1.1. 给一个温度集合, 要返回一个对应长度的结果集合, 这个结果集合里面的元素 i 是 当前 i 位置的元素的下一个更高温度的元素的位置和当前 i 位置的距离之差, 若是当前元素不存在下一个更高温度的元素, 则这个位置用0代替; 2. 思路 本题用单调栈来求解;单调栈就适用于来求当前元素左边或者右边第一个比当前元素大或者小的元素;【单调栈:让栈中的元素保持单调

软考(计算机技术与软件专业技术资格(水平)考试)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。 月下飞天镜,云生结海楼。 ——《渡荆门送别》 信息系统项目管理师备考专栏 软考全称:计算机技术与软件专业技术资格(水平)考试 官网直达:中国计算机技术职业资格网 文章目录 软考介绍1.

风格控制水平创新高!南理工InstantX小红书发布CSGO:简单高效的端到端风格迁移框架

论文链接:https://arxiv.org/pdf/2408.16766 项目链接:https://csgo-gen.github.io/ 亮点直击 构建了一个专门用于风格迁移的数据集设计了一个简单但有效的端到端训练的风格迁移框架CSGO框架,以验证这个大规模数据集在风格迁移中的有益效果。引入了内容对齐评分(Content Alignment Score,简称CAS)来评估风格迁移

双指针(5)_单调性_有效三角形的个数

个人主页:C++忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创 双指针(5)_单调性_有效三角形的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习C++的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. 题目链接: 2.题目描述 : 3.解法 :     解法一(暴力枚举) :     算法思路 :     代码展示 : 暴力枚

n条直线最多能划分出多少个平面?

N条直线,两两相交,其交点各不不同,则产生的交点数目为N个数中取2个数的组合; 同时,也只有这种情况下(两两相交,也交点不同),分割的平面数最多, 数目为: 2 + (N-1)(N+2)/2.  这里求最少平面数没有意义,因为最少平面数就是N+1, 即N条直线两两平行的时候,分割的平面最少。 举例: 1条直线分割平面数最多为2; a1 = 2 2条直线分割平面数最多为4;

机器学习模型中的因果关系:引入单调约束

单调约束是使机器学习模型可行的关键,但它们仍未被广泛使用欢迎来到雲闪世界。 碳ausality 正在迅速成为每个数据科学家工具包中必不可少的组成部分。 这是有充分理由的。 事实上,因果模型在商业中具有很高的价值,因为它们为“假设”情景提供了更可靠的估计,特别是在用于做出影响业务结果的决策时。 在本文中,我将展示如何通过简单的更改(实际上添加一行代码)将传统的 ML 模型(如随机森林、L

单调栈的实现

这是C++算法基础-数据结构专栏的第二十四篇文章,专栏详情请见此处。 引入         单调栈就是满足单调性的栈结构,它最经典的应用就是给定一个序列,找出每个数左边离它最近的比它大/小的数。         下面我们就来讲单调栈的实现。 定义          单调栈就是满足单调性的栈结构,也就是说,其中的元素具有单调性,但是存储的方法和基本操作与栈一样。 过