Melkman的凸包算法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/********************************************************************
ac poj 1113
由于1113输入已经是个简单多边形,故可以直接用melkman求凸包o(n)复杂度
如果输入只是个点集合,就要先排序 再用melkman 复杂度为nlgn
排序可先按照x排,再y排
********************************************************************/

#include
#include
#include


#define N 1002
#define pi 3.141592653589793

struct POINT{
int x,y;
};

int n,l,D[N*2],top,bot;
POINT point[N];

inline double dis(POINT a,POINT b){
double x=a.x-b.x;
double y=a.y-b.y;
return sqrt(x*x+y*y);
}


inline int cross(POINT a,POINT b){
return a.x*b.y-b.x*a.y;
}

int isleft(POINT o,POINT a,POINT b){ //判断ab是不是在oa的左边
POINT x;
POINT y;
x.x=a.x-o.x;
x.y=a.y-o.y;
y.x=b.x-a.x;
y.y=b.y-a.y;
return cross(x,y);
}

void melkman(){
int i,t;

bot=n-1; top=n;
D[top++]=0; D[top++]=1;

for(i=2;iif(isleft(point[D[top-2]],point[D[top-1]],point[i])!=0) break; //寻找第三个点 要保证3个点不共线!!
D[top-1]=i; //共线就更换顶点
}

D[bot--]=i; D[top++]=i; //i是第三个点 不共线!!

if(isleft(point[D[n]],point[D[n+1]],point[D[n+2]])<0){ //此时队列中有3个点,要保证3个点a,b,c是成逆时针的,不是就调换ab
t=D[n];
D[n]=D[n+1];
D[n+1]=t;
}

for(i++;iif(isleft(point[D[top-2]],point[D[top-1]],point[i])>0&& //如果成立就是i在凸包内,跳过
isleft(point[D[bot+1]],point[D[bot+2]],point[i])>0) continue;

while(isleft(point[D[top-2]],point[D[top-1]],point[i])<=0) top--;
D[top++]=i;

while(isleft(point[D[bot+1]],point[D[bot+2]],point[i])<=0) bot++;
D[bot--]=i;
}

// 凸包构造完成,D数组里bot+1至top-1内就是凸包的序列(头尾是同一点)
}

int main(){
freopen("in.txt","r",stdin);
scanf("%d%d",&n,&l);
int i;
for(i=0;i
melkman();
double ans=0;
for(i=bot+1;ians+=2*pi*l;
printf("%.0f\n",ans);
return 0;
}

相关文档
最新文档