| ||||||||||
| 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