1007: [HNOI2008]水平可见直线

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 5932  Solved: 2254
[Submit][Status][Discuss]

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
 
 
 
【题解】
算法比较直观,先按斜率排序,再将最小的两条线入栈,然后依次处理每条线,如果其与栈顶元素的交点在上一个点的左边,则将栈顶元素出栈。
这样为什么对呢?因为对任意一个开口向上的半凸包,从左到右依次观察每条边和每个顶点,发现其斜率不断增大,顶点的横坐标也不断增大。
注意对斜率相同的直线的处理。
 
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define eps 1e-8
struct node{double a,b;int id;}l[],st[];
int n,top,ans[];
inline int read()
{
int x=,f=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-; ch=getchar();}
while(isdigit(ch)) {x=x*+ch-''; ch=getchar();}
return x*f;
}
bool cmp(node x,node y)//斜率相同则按纵截距排序,否则按斜率排序
{
if(fabs(x.a-y.a)<eps) return x.b<y.b;
else return x.a<y.a;
}
double gets(node x,node y) {return (y.b-x.b)/(x.a-y.a);}
void insert(node x)
{
while(top)
{
if(fabs(x.a-st[top].a)<eps) top--; //斜率相同将top弹出
else if(gets(x,st[top])<=gets(st[top],st[top-])&&top>) top--; //交点在左边将top弹出
else break;
}
st[++top]=x;
}
void work()
{
for(int i=;i<=n;i++) insert(l[i]);
for(int i=;i<=top;i++) ans[st[i].id]=;
for(int i=;i<=n;i++) if(ans[i]) printf("%d ",i);
}
int main()
{
n=read();
for(int i=;i<=n;i++) {scanf("%lf%lf",&l[i].a,&l[i].b); l[i].id=i;}
sort(l+,l+n+,cmp);
work();
return ;
}
 
 

【bzoj1007】[HNOI2008]水平可见直线的更多相关文章

  1. [bzoj1007][HNOI2008]水平可见直线_单调栈

    水平可见直线 bzoj-1007 HNOI-2008 题目大意:给你n条直线,为你从上往下看能看见多少跳直线. 注释:能看见一条直线,当且仅当这条直线上存在一条长度>0的线段使得这条线段上方没有 ...

  2. [bzoj1007][HNOI2008][水平可见直线] (斜率不等式)

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

  3. [BZOJ1007] [HNOI2008] 水平可见直线 (凸包)

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

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

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

  5. BZOJ1007:[HNOI2008]水平可见直线(计算几何)

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

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

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

  7. [BZOJ1007](HNOI2008)水平可见直线(半平面交习题)

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

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

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

  9. bzoj1007 [HNOI2008]水平可见直线 - 几何 - hzwer.com

    Description Input 第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi Output 从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必 ...

  10. bzoj1007[HNOI2008]水平可见直线

    cycleke神说要用半平面交(其实他也用的凸包),把我吓了一跳,后来发现(看题解)其实可以先按斜率排序,再将最小的两条线入栈,如果其与栈顶元素的交点在上一个点的左边,则将栈顶元素出栈.这是一个开口向 ...

随机推荐

  1. linux资源监控命令详解

    Linux统计/监控工具SAR详细介绍:要判断一个系统瓶颈问题,有时需要几个 sar 命令选项结合起来使用,例如: 怀疑CPU存在瓶颈,可用 sar -u 和 sar -q deng 等来查看 怀疑内 ...

  2. Asp.net Form登陆认证的回顾学习

    asp.net网站中,我最常用的就是Form认证了,在实现登陆时,利用Form认证实现用户的访问权限,哪些页面是可以匿名登陆,哪些页面需要认证后才能访问,哪些页面不能访问等等权限.我还可在登陆时,使用 ...

  3. POJ--1416

    #include <stdio.h> #include <stdlib.h> ]={};//代表有没有切割的数组 ;//输入的要被切割的数字 ]={};//切完输出的数组成的数 ...

  4. 第一章 管理程序流(In .net4.5) 之 实现多线程和异步处理

    1. 概述 本章主要讲解.net4.5如何实现多线程和异步处理的相关内容. 2. 主要内容 2.1 理解线程 ① 使用Thread类   public static class Program   { ...

  5. JForum二次开发(一)

    1.环境 myeclipse2014,jdk7,tomcat8,mysql5.6 2.下载源码地址 http://jforum.net/download.jsp 3.导入源码 新建web工程JForu ...

  6. 浅谈objective—C管理内存

    这段时间被导师催着论文,调试各种BUg,也是醉了,发现很大程度上,内存出错,栈溢出,各种悲剧.那么今天就和大家一起对OC的内存管理来个探微吧.Objective-C使用一个保留计数记录了我们所创建的所 ...

  7. jpg图片在IE6、IE7和IE8下不显示解决办法

    坑人的IE浏览器,花了我一个小时才找到原因. 原因:IE内核不能渲染CMYK模式的jpg图片,需要转换为RGB模式. 在photoshop里点击菜单栏—图像—RGB模式就行了 引用:http://lg ...

  8. Python 以正确的宽度在盒子中居中打印一个字符

    注意://为整除的意思 代码: # -*- coding:UTF-8 -*- sentence = input("Sentence:") screen_width = 80 tex ...

  9. Android--用DownLoadManager下载完成后启动安装

    当我们用系统的服务DownLoadManager下载完成后,系统会发送一个广播,我们只需要注册一个广播,然后在广播里面写如一些相应的操作. 1.注册广播 completeReceiver = new ...

  10. 2天驾驭DIV+CSS (实战篇)(转)

     这是去年看到的一片文章,感觉在我的学习中,有不少的影响.于是把它分享给想很快了解css的兄弟们.本文是实战篇. 基础篇[知识一] “DIV+CSS” 的叫法是不准确的[知识二] “DIV+CSS” ...