【BZOJ1007】【HNOI2008】水平可见直线(斜率排序+单调栈)
1007: [HNOI2008]水平可见直线
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 2605 Solved: 914
[Submit][Status]
Description

Input
第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi
Output
从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格
Sample Input
-1 0
1 0
0 0
Sample Output
HINT
Source
分析:本蒟残还是太弱,只能膜拜题解:
以下摘自wyl大神的空间:http://hi.baidu.com/wyl8899/item/061d3b0de2c42b344bc4a362
正解是按斜率排序,用栈维护可见直线。
如右图,当前考虑直线now,栈顶top,栈顶的下一个元素top'大致的位置。
显然now和top'将把top完全遮盖。
思考一下可以得出,记两直线交点的横坐标为x(A,B),则x(now,top)<=x(top,top')时,栈顶直线被废,弹出栈。
反复这样操作,直至不满足上面的条件,将当前直线压入栈中。
最后在栈中的直线就是答案。
对了,同斜率的直线,显然只考虑截距最大的那个就好了,因此要处理一下(当然不处理的话x(now,top)的计算过程中要divided by 0)
总结:一般情况下处理多条直线的问题都是将它们按照斜率排序(我发现很多直线题这一步都是基础),而且之后就能用单调性维护(这个也经常见到,比如斜率优化dp里面就是用单调队列,本题用单调栈)
code:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=;
struct wjmzbmr
{
int k,b,w;
bool operator < (const wjmzbmr& x) const
{
return (k<x.k)||((k==x.k)&&(b>x.b));
}
}a[maxn+];
wjmzbmr c[maxn+];
int n,stack[maxn+],b[maxn+];
bool f[maxn+];
bool pd(int now,int top,int ltop)
{
double x1=(double)(c[top].b-c[now].b)/(double)(c[now].k-c[top].k);
double x2=(double)(c[top].b-c[ltop].b)/(double)(c[ltop].k-c[top].k);
if(x2-x1>=0.0) return true;else return false;
}
int main()
{
freopen("ce.in","r",stdin);
freopen("ce.out","w",stdout);
scanf("%d",&n);
for(int i=;i<n;++i)
{
scanf("%d%d",&a[i].k,&a[i].b);
a[i].w=i;
c[i]=a[i];
}
sort(a,a+n);
int size=;b[size]=a[].w;
for(int i=;i<n;++i) if(a[i].k!=a[i-].k) b[++size]=a[i].w;
int len=;
memset(stack,,sizeof(stack));
stack[]=b[],stack[]=b[];
for(int i=;i<=size;++i)
{
while(len>=&&pd(b[i],stack[len],stack[len-])) --len;
stack[++len]=b[i];
}
memset(f,,sizeof(f));
for(int i=;i<=len;++i) f[stack[i]]=;
for(int i=;i<n;++i) if(f[i]==) printf("%d ",i+);
return ;
}
【BZOJ1007】【HNOI2008】水平可见直线(斜率排序+单调栈)的更多相关文章
- 【bzoj1007】[HNOI2008]水平可见直线 半平面交/单调栈
题目描述 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.例如,对于直线:L1:y=x; L2:y=- ...
- BZOJ.1007.[HNOI2008]水平可见直线(凸壳 单调栈)
题目链接 可以看出我们是要维护一个下凸壳. 先对斜率从小到大排序.斜率最大.最小的直线是一定会保留的,因为这是凸壳最边上的两段. 维护一个单调栈,栈中为当前可见直线(按照斜率排序). 当加入一条直线l ...
- [bzoj1007][HNOI2008][水平可见直线] (斜率不等式)
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的,否则Li为被覆盖的. 例如,对于直线: L1:y ...
- [bzoj1007][HNOI2008]水平可见直线_单调栈
水平可见直线 bzoj-1007 HNOI-2008 题目大意:给你n条直线,为你从上往下看能看见多少跳直线. 注释:能看见一条直线,当且仅当这条直线上存在一条长度>0的线段使得这条线段上方没有 ...
- BZOJ1007: [HNOI2008]水平可见直线(单调栈)
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8638 Solved: 3327[Submit][Status][Discuss] Descripti ...
- bzoj1007: [HNOI2008]水平可见直线 单调栈维护凸壳
在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.例如,对于直线:L1:y=x; L2:y=-x; L3 ...
- bzoj1007 [HNOI2008]水平可见直线——单调栈
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1007 可以把直线按斜率从小到大排序,用单调栈维护,判断新直线与栈顶的交点和栈顶与它之前直线的 ...
- BZOJ1007:[HNOI2008]水平可见直线(计算几何)
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的,否则Li为被覆盖的. 例如,对于直线: L1:y ...
- bzoj1007 [HNOI2008]水平可见直线 - 几何 - hzwer.com
Description Input 第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi Output 从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必 ...
随机推荐
- 最近学习linux常用命令。
一.文件系统的管理tips:输入命令的时候要常用tab键来补全 ls 查看目录信息 ( ls / ) ls -l 等价于 llpwd 查看当前所处的路径 cd 切换目录 (cd /) ,如果不带参数则 ...
- Elasticsearch Scripts disabled
Es 2.2版本中,在查询语句中使用script 时,提示如下错误 scripts of type [inline], operation [aggs] and lang [groovy] are d ...
- cordova 环境搭建
安装环境前题是nodejs已安装,android环境搭建完成,android环境没有通过http://www.androiddevtools.cn/安装,安装使用 淘宝 NPM 镜像 方式 1.运行c ...
- JavaScript中的直接量与初始器的区别
很多代码优化及公司规范都会提到 写对象不应该 var obj = new Object() 而应该 var obj = {} 写数组不应该 var arr = new Array() 而应该 var ...
- noip2014提高组day2二题题解-rLq
(又是昨天的作业……本题写于昨天) (这破题都做这么久,我是不是吃枣药丸……) (好吧这是一道图论题呢) 本题地址:http://www.luogu.org/problem/show?pid=2296 ...
- POJ 3321 Apple Tree
树状数组. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cm ...
- C++基础笔记(四)C++内存管理
析构函数 * 析构函数在对象所占用内存释放时调用,通常用来释放相关的资源 * 析构函数就是一个特殊的类成员函数,它是构造函数相反 构造函数:对象在分配内存之后,立即调用 析构函数:对象在内存被释放之前 ...
- 测试 Mono 安装
测试 Mono 安装 为了测试核心编译器(mcs)和运行时(mono),应该创建一个简单的程序并编译它.可以在喜欢的任何文本编辑器中创建程序.这里采用一种快速而简陋的方法创建该文件(虽然没有任何格式化 ...
- Android--使用VideoView播放视频
承香墨影 Android--使用VideoView播放视频 前言 之前有讲过如何使用SurfaceView配合MediaPlayer播放视频,其实Android还为开发人员提供了另外一种更简单 ...
- Volley(四)—— ImageLoader & NetworkImageView
Volley(四)—— ImageLoader & NetworkImageView ImageLoader是一个加载网络图片的封装类,其内部还是由ImageRequest来实现的.但因为源码 ...