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 }

 

posted @ 2018-01-02 20:23  大奕哥&VANE  阅读(265)  评论(0编辑  收藏  举报