Description

在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.
    例如,对于直线:
    L1:y=x; L2:y=-x; L3:y=0
    则L1和L2是可见的,L3是被覆盖的.
    给出n条直线,表示成y=Ax+B的形式(|A|,|B|<=500000),且n条直线两两不重合.求出所有可见的直线.

Input

第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi

Output

从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格

Sample Input

3
-1 0
1 0
0 0

Sample Output

1 2

HINT

 

Source

两种做法吧:

  1. 直接半平面交暴搞,虽然我不会写;
  2. 第二种主要是针对这个题目的: 利用题所隐藏的性质。稍微YY一下,所能看到的直线沿着X正方向斜率一定是单调递增的。

  首先将斜率排序(从小到大)之后一次加入栈中。对于栈顶直线l1,次顶直线l2,以及所枚举到的直线i,如果l与l1的交点在l1与l2交点左方,栈顶的弹出(证明:画画图就知道了)。

  最后栈中的直线即为答案。(这个好像就是半平面交)

代码如下:

 #include<cstdlib>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std; #define esp (1e-6)
#define maxn 50010
int n,S[maxn],top;
vector <int> vec;
struct Line{double A,B; int ord;}line[maxn]; inline bool cmp(Line a,Line b)
{
if (a.A == b.A) return a.B > b.B;
return a.A < b.A;
} inline double calc(Line a,Line b) {return (double)(b.B-a.B)/(double)(a.A-b.A);} inline bool okay(double a,double b)
{
if (a + esp > b &&a-esp<b) return true;
if (a > b) return true;
return false;
} inline void work()
{
int i;
S[++top] = ; i = ;
while (i <= n&&line[i].A == line[i-].A) i++;
if (i <= n)
{
S[++top] = i; ++i;
while (i <= n&&line[i].A == line[i-].A) i++;
for (;i <= n;++i)
{
if (line[S[top]].A == line[i].A)
continue;
else
{
while (top > && okay(calc(line[S[top]],line[S[top-]]),calc(line[S[top]],line[i])))
--top;
S[++top] = i;
}
}
}
for (i = ;i <= top;++i) vec.push_back(line[S[i]].ord);
sort(vec.begin(),vec.end());
} int main()
{
freopen("1007.in","r",stdin);
freopen("1007.out","w",stdout);
scanf("%d",&n); int i;
for (i = ;i <= n;++i)
{
scanf("%lf %lf",&line[i].A,&line[i].B);
line[i].ord = i;
}
sort(line+,line+n+,cmp);
work();
int nn = vec.size();
for (i = ;i < nn;++i) printf("%d ",vec[i]);
fclose(stdin); fclose(stdout);
return ;
}

BZOJ 1007 水平可见直线的更多相关文章

  1. BZOJ 1007 水平可见直线 | 计算几何

    BZOJ 1007 水平可见直线 题面 平面直角坐标系上有一些直线,请求出在纵坐标无限大处能看到哪些直线. 题解 将所有直线按照斜率排序(平行的直线只保留最高的直线),维护一个栈,当当前直线与栈顶直线 ...

  2. 【BZOJ】1007 水平可见直线

    [分析] 维护一个下凸包. 首先依照斜率来从小到大排序. 考虑斜率同样的,肯定仅仅能选截距大的,把截距小的给筛掉. 然后用栈来维护下凸包.先压入前两条直线. 然后对于每一条直线i,设栈中上一条直线p= ...

  3. 【BZOJ】【1007】【HNOI2008】水平可见直线

    计算几何初步 其实是维护一个类似下凸壳的东西?画图后发现其实斜率是单调递增的,交点的横坐标也是单调递增的,所以排序一下搞个单调栈来做就可以了…… 看了hzwer的做法…… /************* ...

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

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

  5. BZOJ 1007 [HNOI2008]水平可见直线

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

  6. 2018.07.03 BZOJ 1007: [HNOI2008]水平可见直线(简单计算几何)

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec Memory Limit: 162 MB Description 在xoy直角坐标平面上有n条直线L1,L2,-Ln, ...

  7. BZOJ 1007 [HNOI2008]水平可见直线 (栈)

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

  8. BZOJ 1007: [HNOI2008]水平可见直线 栈/计算几何

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MB 题目连接 http://www.lydsy.com/JudgeOnline ...

  9. BZOJ 1007: [HNOI2008]水平可见直线 平面直线

    1007: [HNOI2008]水平可见直线 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则 ...

随机推荐

  1. PDOstament对象执行execute()函数,只要是sql语句正确都是返回true

    [PDO对象操作数据库] PDOstament对象执行execute()函数,只要是sql语句正确都是返回true. 问题: 想要PDO对象实现更改一条记录, 并修改是否成功要返回信息给用户. 上我的 ...

  2. c++拷贝构造函数(深拷贝,浅拷贝)详解

    一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: ; int b=a;   而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面 ...

  3. 支付宝手机网站支付流程(Node实现)

    前言 公司M站要接入支付宝,借机研究了一下支付宝的支付流程.毕竟,只有公司才能拿到支付接口权限. 主要参考文档: https://doc.open.alipay.com/doc2/detail?tre ...

  4. U盘安装centos 6.4教程(总算是弄好了

    参考:http://blog.chinaunix.net/uid-27666459-id-3342477.html http://www.linuxidc.com/Linux/2011-05/3569 ...

  5. mysql默认用户名和密码

    默认用户名:root 密码:gree..

  6. C#压缩文件为zip格式

    Vercher   C#压缩文件为zip格式 需要ICSharpCode.SharpZipLib.dll,网上下载的到. 代码是从网上找来的: 1 public class ZipClass 2 { ...

  7. $(this).next()与$(this).children()

    $(this).next() 当前元素同级的下个元素,而非子元素 $(this).children() 是当前元素的下一级元素的集合,就是子元素的集合,而不管子元素的后代元素 所以这两个没有什么可比性 ...

  8. 彻底删除mysql的方法(有隐藏文件)

    1.建议使用360进行卸载,可以彻底卸载软件 2.360会提醒删除注册表 3.这个隐藏文件要删除掉 在 C:\Documents and Settings\ 路径下搜索 MySQL 文件夹(默认隐藏的 ...

  9. 如何在安卓/data(而不是/data/data)目录下进行文件的读写操作

    分析:Android默认是无法直接操作/data目录的,只能读写程序自己的私有目录,也就是/data/data/package name/下,默认只能操作这个目录下的文件,也就是我们想直接读写/dat ...

  10. SlidingMenu侧换菜单的导入

    对于Adt-22.3有一种使用SlidingMenu(侧滑菜单的方式),直接加你放到lib文件夹下