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 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。