BZOJ1007 水平相交直线

按照斜率排序,我们可以想象如果你能看到大于等于三条直线那么他一定会组成一个下凸包,这样我们只需要判断如果当前这条直线与栈顶第二直线相交点相比于栈顶第二直线与栈顶直线相交点靠左那么他就不满足凸包性质。

画画图想想看。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1000005;
 4 double eps=1e-8;
 5 bool ans[1000005];
 6 struct node
 7 {
 8     double k,b;int id;
 9     bool operator <(const node &x)const{
10         if(fabs(k-x.k)<=eps)return b<x.b;
11         return k<x.k;
12     }
13 }l[N],sta[N];
14 int top=0;int n;
15 double calc(node x,node y)
16 {
17     return (y.b-x.b)/(x.k-y.k);
18 }
19 void add(node p)
20 {
21     while(top)
22     {
23         if(fabs(sta[top].k-p.k)<=eps){top--;continue;}
24         else if(top>1&&calc(p,sta[top-1])<=calc(sta[top-1],sta[top]))top--;
25         else break;
26     }
27     sta[++top]=p;
28 }
29 void work()
30 {
31     for(int i=1;i<=n;++i)add(l[i]);
32     for(int i=1;i<=top;++i)ans[sta[i].id]=1;
33     for(int i=1;i<=n;++i)
34     {
35         if(ans[i])printf("%d ",i);
36     }
37 }
38 int main()
39 {
40     scanf("%d",&n);
41     for(int i=1;i<=n;++i)
42     {
43         scanf("%lf%lf",&l[i].k,&l[i].b);l[i].id=i;
44     }
45     sort(l+1,l+1+n);
46     work();
47     return 0;
48 }

原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8178979.html

时间: 2024-10-04 20:31:01

BZOJ1007 水平相交直线的相关文章

[BZOJ1007]水平可见直线

发现其实是一个下凸壳,所以先按斜率排序,然后判断当前直线与栈顶直线的交点是否更靠右 注意平行的情况 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 #define maxn 50005 5 #define esp 1e-8 6 struct node{ 7 double a,b; 8 int id; 9 }V[maxn]; 10 double a[maxn],b[maxn]; 11 int sta[maxn],top; 12 bool

BZOJ1007|水平可见直线|模拟

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,BiOutput从小到大输出可见直

[HNOI2008] [BZOJ1007] 水平可见直线

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行输入A

【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

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

[BZOJ1007]水平可见直线(单调栈) 题解 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 < 50

bzoj1007: [HNOI2008]水平可见直线(单调栈)

1007: [HNOI2008]水平可见直线 题目:传送门 题解: 蒟蒻在bzoj上做的第一道计算几何 其实这道题并不难...(所以我A了) 仔细想想不难发现,其实我们只需要维护一个下凸的图形... 只有在这个图形上的直线才不会被覆盖,也就是可以被上帝直线看到的孩子 为什么呢...自己画个图模拟吧. 那么具体的做法我们就要采用单调栈啦! 把给出的直线按照斜率从小到大排序(如果斜率相同的话就按照b来排) 然后一个一个放入我们强大的单调栈中,在加入的同时我们当然还要进行维护: 如果栈顶的直线与新加直

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

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1007 给出一些直线,沿着y轴从上往下看,能看到多少条直线. 分析 由于直线相交,会遮挡住一些直线. 自己画画图就可以发现,最后能看见的直线,也就是在最上面的那些直线一定构成一个凸包的下凸壳(没错一定是凸的). 接下来就是如何求这个下凸壳了. 先按照斜率为第一关键字,截距为第二关键字,将直线从小到大排序.用一个斜率单调递增的栈来维护凸壳. 我们按照排序后的顺序添加直线,画画图会发现: 1.斜率

BZOJ 1007: [HNOI2008]水平可见直线 几何

按斜率排序,斜率线相同的直线取截距最大的 一条直线能够被看到的条件是,与比它斜率小的交点在比它斜率大的交点的左侧 1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 4234  Solved: 1558 [Submit][Status][Discuss] Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则

bzoj 1007 水平可见直线 半平面交稀里糊涂的过了...

题意:按y=Ax+B的形式给出n(<=50000)条直线,求从y值为无穷大的地方向下看能看到的直线编号 一看到题目就想到半平面交,以每条直线的上方为一个半平面,求半平面的交,交集中存在的直线就是能看到的直线 但是写出来之后发现样例都过不了... 对于样例,如果允许半平面在边界处重叠那么答案是1,2,3,如果不允许只有1.. 然后抱着试一试的心理交上去了,结果竟然直接AC了.. 后来看题解只需要考虑交点x坐标.. bzoj 1007 水平可见直线 半平面交稀里糊涂的过了...,布布扣,bubuko