Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
雁过留声——正确的判共线是AC的凸包的一半这题的思路很明确:result=2*pi*L+凸包周长 于是就变成求凸包的题了。 我默写了排序+扫描的那个代码,交上去,突然,wa了。 为什么?难道有陷阱? 我随手输入: 10 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 并打印得到的凸包: (1 0) (6 0) (10 0) 怎么会是这样?(6 0)? 突然明白:必须要再斜率排序遇到共线时特判! 有人写的凸包会把共线的点滤掉。 我的方法:让距离基准点近的点在排序时靠前,就ok了。 给个代码: (呵呵,我手写了一个sqrt,比较极端...都怪OI用的那个对数学库不友好的编译器......) int N,L; int X[NMax],Y[NMax]; int List[NMax],Lc; void qs(int b,int e){if (b>=e)return; int j,t; t=X[b];X[b]=X[(b+e)>>1];X[(b+e)>>1]=t; t=Y[b];Y[b]=Y[(b+e)>>1];Y[(b+e)>>1]=t; for (int i=j=b+1;i<=e;i++) if ((X[i]-X[0])*(Y[b]-Y[0])-(X[b]-X[0])*(Y[i]-Y[0])>0 || (X[i]-X[0])*(Y[b]-Y[0])-(X[b]-X[0])*(Y[i]-Y[0])==0 && (X[i]-X[0])*(X[i]-X[0])<(X[b]-X[0])*(X[b]-X[0]) ////////////////////////////////////// 排序时对共线点的处理 ////////////////////////////////////// ){ t=X[i];X[i]=X[j];X[j]=t; t=Y[i];Y[i]=Y[j];Y[j]=t; j++; } --j; t=X[b];X[b]=X[j];X[j]=t; t=Y[b];Y[b]=Y[j];Y[j]=t; qs(b,j-1);qs(j+1,e); } void ConvexHull(){ int t; for (int i=0;i<N;i++) if (Y[i]<Y[0] || Y[i]==Y[0] && X[i]<X[0]){ t=X[i];X[i]=X[0];X[0]=t; t=Y[i];Y[i]=Y[0];Y[0]=t; } qs(1,N-1); Lc=0; for (int i=0;i<N;i++){ while (Lc>=3 && (X[i]-X[List[Lc-1]])*(Y[List[Lc-2]]-Y[List[Lc-1]]) <= /////////////////////////////// 这里用<=而不用<是为了去掉最终凸包中共线的点 /////////////////////////////// (Y[i]-Y[List[Lc-1]])*(X[List[Lc-2]]-X[List[Lc-1]]) )Lc--; List[Lc++]=i; } } double Sqrt(double a){ double x,y; x=a;y=(x+a/x)/2.0; while (y-x>0.0000001 || y-x<-0.0000001){ x=y;y=(x+a/x)/2.0; } return y; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator