水平可见直线 bzoj-1007 HNOI-2008

    题目大意:给你n条直线,为你从上往下看能看见多少跳直线。

    注释:能看见一条直线,当且仅当这条直线上存在一条长度>0的线段使得这条线段上方没有其他直线,$1\le n 5\cdot 10^4$。

      想法:神题qwq。看见网上的做法突然有一种学计算几何的冲动,直到看见一篇大神的blog说用单调栈做?这题困难其实就困难在如何规定两条直线之间本不存在的单调性。用单调栈就是讲即将进栈元素不断和栈顶比较,然后弹来弹去最后剩下的都是可见的。不容易难想到:将直线先按斜率排序。如果两直线斜率相等那么截距小的那个自然直接gg。

      显然,当待入栈直线和栈顶直线的交点直接决定了栈顶直线是否仍有存在的意义。如果$l_3$和$l_2$的交点在x左侧,那么显然,$l_2$就可以滚犊犊了。以此类推,即可。

    最后,附上丑陋的代码... ...

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1000010
using namespace std;
struct Node
{
double k,b;
int id;
}l[N];
inline bool cmp(Node a,Node b)
{
if(a.k!=b.k) return a.k<b.k;
return a.b>b.b;
}
double getpos(Node a,Node b)
{
return (b.b-a.b)/(a.k-b.k);
}
int s[N];
bool ans[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&l[i].k,&l[i].b);
l[i].id=i;
}
sort(l+1,l+1+n,cmp);
int top=1;
s[1]=1;
for(int i=2;i<=n;i++)
{
if( l[i].k-l[i-1].k < 1e-8) continue;
while(top > 1&& getpos(l[i],l[s[top]]) <= getpos(l[s[top]],l[s[top-1]]) ) top--;
s[++top]=i;
}
for(int i=1;i<=top;i++) ans[l[s[i]].id]=1;
for(int i=1;i<=n;i++)
{
if(ans[i])
{
printf("%d ",i);
}
}
puts("");
return 0;
}

    小结:对于这种问题将已知的元素排序,并将它们强行化作单调的情况,是不必要但可行的。

[bzoj1007][HNOI2008]水平可见直线_单调栈的更多相关文章

  1. 【BZOJ1007】水平可见直线(单调栈)

    [BZOJ1007]水平可见直线(单调栈) 题解 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的 ...

  2. BZOJ_1007_ [HNOI2008]_水平可见直线_(单调栈+凸包)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1007 给出一些直线,沿着y轴从上往下看,能看到多少条直线. 分析 由于直线相交,会遮挡住一些直 ...

  3. bzoj 1007 [HNOI2008]水平可见直线(单调栈)

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5120  Solved: 1899[Submit][Sta ...

  4. 【洛谷 P3194】 [HNOI2008]水平可见直线 (单调栈)

    题目链接 把线段以斜率为第一关键字,截距为第二关键字升序排序. 然后维护一个单调栈,保证栈中两两线段的交点的\(x\)坐标单调上升就行了.栈中的线段即为所求. #include <cstdio& ...

  5. _bzoj1007 [HNOI2008]水平可见直线【单调栈】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1007 按斜率排序,去掉斜率相同时,截距较小的直线(即只保留该斜率下截距最大的直线).若当前直 ...

  6. BZOJ1007: [HNOI2008]水平可见直线(单调栈)

    Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8638  Solved: 3327[Submit][Status][Discuss] Descripti ...

  7. bzoj1007: [HNOI2008]水平可见直线 单调栈维护凸壳

    在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.例如,对于直线:L1:y=x; L2:y=-x; L3 ...

  8. bzoj1007 [HNOI2008]水平可见直线——单调栈

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1007 可以把直线按斜率从小到大排序,用单调栈维护,判断新直线与栈顶的交点和栈顶与它之前直线的 ...

  9. 【BZOJ1007】【HNOI2008】水平可见直线 几何 单调栈

    题目大意 给你\(n\)条直线\(y=kx+b\),问你从\(y\)值为正无穷大处往下看能看到那些直线. \(1\leq n\leq 500000\) 题解 如果对于两条直线\(l_i,l_j\),\ ...

随机推荐

  1. Android之NDK开发(转载)

    http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C+ ...

  2. hibernate字段名和属性

    字段名和属性名相同 Annotation:默认为@Basic 注意:如果在成员属性没有加入任何注解,则默认在前面加入了@Basic Xml中不用写column 字段名和属性名不同 Annotation ...

  3. mongoDB的基本用法

    一.MongoDB初识 什么是MongoDB MongoDB是一个基于分布式文件存储的数据库.由c++语言编写.旨在为web应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库 ...

  4. jq-文本框只能输入数字

    <input type="text" onKeyUp="value=value.replace(/\D/g,'')"  /> onKeyUp: 当输 ...

  5. Java系列学习(七)-面向对象

    1.成员变量和局部变量的区别 (1)在类中的位置不同 成员变量:类中 方法外 局部变量:方法中 (2)在内存中的位置不同 成员变量:在堆中 局部变量:在栈中 (3)生命周期不同 成员变量:随着对象的创 ...

  6. 关于debug.keystore文件用法以及错误处理

    在开发过程中需要频繁的为测试的同事签名apk,非常很麻烦,把默认debug.keystore文件替换成发布用(生产环境)的签名文件,不用频繁地签名apk文件了.      如果直接使用生产keysto ...

  7. React Native真机调试安卓版

    React Native真机调试安卓版 一.准备工作 1.1 环境搭建 React Native中文网的文档已经非常清晰地描述了,按照步骤即可.http://reactnative.cn/docs/0 ...

  8. php中的抽象方法和抽象类

    1.什么是抽象方法?    我们在类里面定义的没有方法提的方法就是抽象方法.所谓的没有方法体指的是,在声明的时候没有大括号以及其中的内容,而是直接在声明时在方法名后加上分号结束,另外在声明抽象方法时方 ...

  9. MySQL实现当前数据表的所有时间都增加或减少指定的时间间隔

    DATE_ADD() 函数向日期添加指定的时间间隔. 当前表所有数据都往后增加一天时间: UPDATE ACT_BlockNum SET CreateTime = DATE_ADD(CreateTim ...

  10. DDX DDV 用法

    DDX:Dialog Data Exchange 如果使用DDX机制,一般会在OnInitDialog消息处理函数或Dialog构造函数中,为对话框对象的成员变量设置了初始值.在对话框显示前,框架的D ...