码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1007 水平相交直线

时间:2018-01-02 23:30:31      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:bre   需要   tin   大于   top   scanf   class   for   组成   

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

画画图想想看。

 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 }

 

BZOJ1007 水平相交直线

标签:bre   需要   tin   大于   top   scanf   class   for   组成   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!