必须对平行线的情况特殊判断。
当斜率最小的两条直线是平行线的时候,求出线的集合会存在平行线。 |
|
#include<bits/stdc++.h>
#define RG register #define il inline #define N 50010 #define db double using namespace std; struct point{ db x,y; point() {} point(db _x,db _y):x(_x),y(_y) {} 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 db k)const{return point (k*x,k*y);} db operator * (const point & a){return x*a.y-y*a.x;} }; struct line{ db k,b;int id; line() {} line(db K,db B,int I):k(K),b(B),id(I) {} }l[N]; int que[N]; bool comp(const line & a,const line & b){return a.k<b.k;} int n,ans[N]; bool check(line l1,line l2,line l0){ db k1=l1.k,b1=l1.b,k2=l2.k,b2=l2.b; db k3=l0.k,b3=l0.b;db kk,bb,kkk,bbb; if(k1-k2<0)kk=k2-k1,bb=b1-b2;else kk=k1-k2,bb=b2-b1; if(k3-k2<0)kkk=k2-k3,bbb=b3-b2;else kkk=k3-k2,bbb=b2-b3; return bb*kkk>bbb*kk; } int main(){ freopen("bzoj_1007.in","r",stdin); freopen("bzoj_1007.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;++i){ db k,b;scanf("%lf%lf",&k,&b); l[i]=line(k,b,i); }sort(l+1,l+n+1,comp);int top=2; que[1]=1,que[2]=2; for(int i=3;i<=n;++i){ while(top>=2&&check(l[que[top-1]],l[que[top]],l[i]))top--; que[++top]=i; }if(n==1)cout<<1<<" ",exit(0); for(int i=1;i<=top;++i)ans[++ans[0]]=l[que[i]].id; sort(ans+1,ans+ans[0]+1); for(int i=1;i<=ans[0];++i)printf("%d ",ans[i]); return 0; }
题目 1831 [HNOI 2008]水平可见直线
2017-07-24 12:03:51
|
|
手工化简一下式子,直接long long就行了,根本不存在精度问题啊……
|
|
|
|
|
|
人神共愤的精度问题。。。。。。
|
|
回复 @Asm.Def : 现在已经rank17了。
|
|
。。为什么我每次退队之前都要判断是否队为空。。
不可能为空的啊。。。 |
|
题目 1831 [HNOI 2008]水平可见直线
2014-12-02 11:55:54
|
|
此题和1634.赛车重了吧。。
题目 1831 [HNOI 2008]水平可见直线
2014-12-02 08:45:37
|
|
裸的半平面交……第一次写计算几何太没经验,真去写了个double二元组存交点……不用说,浮点误差WA到死……其实只要把不等式两边都变成乘法就可以了= =
(这份代码目前在bzoj上rank 3>_<) |