【BZOJ1007】[HNOI2008]水平可见直线 半平面交
【BZOJ1007】[HNOI2008]水平可见直线
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
-1 0
1 0
0 0
Sample Output
题解:本人懒,直接用的半平面交。当然由于本题的特殊性质(都是取上半平面),所以我们可以将单调队列换成单调栈。
由于精度问题,本题需要将eps去掉。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=50010;
const double alpha=1.23456789;
struct point
{
double x,y;
point() {}
point(double a,double b){x=a,y=b;}
point operator + (const point &a) const {return point(x+a.x,y+a.y);}
point operator - (const point &a) const {return point(x-a.x,y-a.y);}
point operator * (const double &a) const {return point(x*a,y*a);}
double operator * (const point &a) const {return x*a.y-y*a.x;}
};
struct line
{
point p,v;
double a;
int org;
line() {}
line(point x,point y,int z){p=x,v=y,a=atan2(v.y,v.x),org=z;}
}l[maxn];
int q[maxn],ans[maxn];
int h,t,n;
point getp(line l1,line l2)
{
point u=l1.p-l2.p;
double temp=(l2.v*u)/(l1.v*l2.v);
return l1.p+l1.v*temp;
}
bool onlft(line a,point b)
{
return a.v*(b-a.p)>0;
}
bool cmp(line a,line b)
{
if(fabs(a.a-b.a)==0) return !onlft(a,b.p);
return a.a<b.a;
}
void HPI()
{
sort(l+1,l+n+1,cmp);
int i,cnt;
for(i=2,cnt=1;i<=n;i++) if(fabs(l[i].a-l[cnt].a)>0) l[++cnt]=l[i];
h=t=q[1]=1;
for(i=2;i<=cnt;i++)
{
while(h<t&&!onlft(l[i],getp(l[q[t]],l[q[t-1]]))) t--;
while(h<t&&!onlft(l[i],getp(l[q[h]],l[q[h+1]]))) h++;
q[++t]=i;
}
//while(h<t&&onlft(l[q[h]],getp(l[q[t]],l[q[t-1]]))) t--;
//while(h<t&&onlft(l[q[t]],getp(l[q[h]],l[q[h+1]]))) h++;
}
int main()
{
scanf("%d",&n);
int i;
double a,b;
for(i=1;i<=n;i++) scanf("%lf%lf",&a,&b),l[i]=line(point(0,b),point(1,a),i);
HPI();
for(i=h;i<=t;i++) ans[++ans[0]]=l[q[i]].org;
sort(ans+1,ans+ans[0]+1);
for(i=1;i<=ans[0];i++) printf("%d ",ans[i]);
return 0;
}
【BZOJ1007】[HNOI2008]水平可见直线 半平面交的更多相关文章
- bzoj 1007: [HNOI2008]水平可见直线 半平面交
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=1007; 题解 其实就是求每条直线的上半部分的交 所以做裸半平面交即可 #include ...
- [日常摸鱼]bzoj1007[HNOI2008]水平可见直线-半平面交(对偶转凸包)
不会写半平面交-然后发现可以转成对偶凸包问题 具体见这里:http://trinkle.blog.uoj.ac/blog/235 相关的原理我好像还是不太懂-orz #include<cstdi ...
- [bzoj1007][HNOI2008]水平可见直线_单调栈
水平可见直线 bzoj-1007 HNOI-2008 题目大意:给你n条直线,为你从上往下看能看见多少跳直线. 注释:能看见一条直线,当且仅当这条直线上存在一条长度>0的线段使得这条线段上方没有 ...
- bzoj1007 [HNOI2008]水平可见直线 - 几何 - hzwer.com
Description Input 第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi Output 从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必 ...
- [bzoj1007][HNOI2008][水平可见直线] (斜率不等式)
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的,否则Li为被覆盖的. 例如,对于直线: L1:y ...
- bzoj1007[HNOI2008]水平可见直线
cycleke神说要用半平面交(其实他也用的凸包),把我吓了一跳,后来发现(看题解)其实可以先按斜率排序,再将最小的两条线入栈,如果其与栈顶元素的交点在上一个点的左边,则将栈顶元素出栈.这是一个开口向 ...
- [BZOJ1007] [HNOI2008] 水平可见直线 (凸包)
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 例如,对于直线:L1:y=x ...
- BZOJ1007: [HNOI2008]水平可见直线(单调栈)
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8638 Solved: 3327[Submit][Status][Discuss] Descripti ...
- BZOJ1007:[HNOI2008]水平可见直线(计算几何)
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的,否则Li为被覆盖的. 例如,对于直线: L1:y ...
随机推荐
- util.date.js
ylbtech-JavaScript-util: util.date.js 日期处理工具 1.A,JS-效果图返回顶部 1.B,JS-Source Code(源代码)返回顶部 1.B.1, m.y ...
- vi中使用“/”查找字符
在vi 文件中使用"/"查找字符串 命令模式下,输入 /word 后回车,即查找word,按 n 查找下一个匹配单词,按 N 查找上一个匹配单词.
- 安装docker-compose的两种方式
这里简单介绍下两种安装docker-compose的方式,第一种方式相对简单,但是由于网络问题,常常安装不上,并且经常会断开,第二种方式略微麻烦,但是安装过程比较稳定 方法一: # curl -L h ...
- 在c++代码中执行bat文件 【转】
我想在c++代码中执行磁盘上的一个bat文件. 这个bat文件的完整路径是:E:\\7z\\my7z.bat. 方法一: system("E:\\7z\\my7z.bat"); s ...
- barrier and Fence
barrier 管理的是commandbuffer里面 command之间 fence管理的是queue之间 queue和cpu之间的顺序 通过flag比如等待所有面片画完 ------------- ...
- python项目构建工具zc.buildout
转载:http://blog.csdn.net/u011630575/article/details/52940099 buildout简介 Buildout 是一个基于Python的构建工具, Bu ...
- devops流程
学习资源: https://www.youtube.com/watch?v=JBtWxj9l7zM&list=PLoYCgNOIyGAAzevEST2qm2Xbe3aeLFvLc&t= ...
- Oracle基础(二) 创建数据库实例
Oracle中数据库也称为数据库实例,在Oracle在安装过程中可以选择创建数据库,也可以再安装之后再进行创建. 一般创建数据库可以使用图形界面方式和SQL指令的方式,由于SQL指令方式较为复杂,这里 ...
- js获取屏幕高度/浏览器高度
1.window.screen.height window.screen.height:设备显示屏的高度 (1)分辨率为1080px的显示屏 (2)手机屏 2.window.screen.avail ...
- iOS 实现启动屏动画(Swift实现,包含图片适配)
代码地址如下:http://www.demodashi.com/demo/12090.html 准备工作 首先我们需要确定作为宣传的图片的宽高比,这个一般是与 UI 确定的.一般启动屏展示会有上下两部 ...