poj-2187-凸包-旋转卡壳法求直径
2014-01-06 13:33
411 查看
先求出凸包,时间复杂度O(n*log(n))
然后运用旋转卡壳发求出凸包的直径。
旋转卡壳法:
1.先求出y坐标最大的点为maxx,y最小的点为minn。
2.过minn,maxx点做一条平行于x轴的直线
3.俩直线分别对minn,maxx点逆时针旋转至某一条直线与凸包的某个点相交为止。
4,用交点更新前一个点。
5,重复3-4直至目前两点都出现过为止。
6,每次旋转之后得到的两点之间的距离的最大值即为凸包的直径
原理:
第一步寻找到的一对点(minn,maxx)一定是一对对踵点。
然后旋转直线会得到另外一对对踵点。
这样一直旋转就会得到所有的对踵点。
然后凸包的直径是某个对踵点直径的距离。
然后运用旋转卡壳发求出凸包的直径。
旋转卡壳法:
1.先求出y坐标最大的点为maxx,y最小的点为minn。
2.过minn,maxx点做一条平行于x轴的直线
3.俩直线分别对minn,maxx点逆时针旋转至某一条直线与凸包的某个点相交为止。
4,用交点更新前一个点。
5,重复3-4直至目前两点都出现过为止。
6,每次旋转之后得到的两点之间的距离的最大值即为凸包的直径
原理:
第一步寻找到的一对点(minn,maxx)一定是一对对踵点。
然后旋转直线会得到另外一对对踵点。
这样一直旋转就会得到所有的对踵点。
然后凸包的直径是某个对踵点直径的距离。
#include<string.h> #include<algorithm> #include<stdlib.h> #include<iostream> #include<stdio.h> #include<vector> #define INF 1000000 using namespace std; struct list { int x,y; } node[50051],tu[50051]; int ts,n; int vis[50051]; int len(struct list a,struct list b) { int xx=a.x-b.x; int yy=a.y-b.y; return xx*xx+yy*yy; } int cmp1(struct list a,struct list b) { if(a.y!=b.y)return a.y<b.y; return a.x<b.x; } int cmp2(struct list a,struct list b) { int x1=a.x-node[1].x; int x2=b.x-node[1].x; int y1=a.y-node[1].y; int y2=b.y-node[1].y; if(x1*y2==x2*y1)return len(a,node[1])<len(b,node[1]); return x1*y2>x2*y1; } void push(int i) { if(ts<=2) { tu[ts++]=node[i]; return ; } int x1=tu[ts-1].x-tu[ts-2].x; int y1=tu[ts-1].y-tu[ts-2].y; int x2=node[i].x-tu[ts-1].x; int y2=node[i].y-tu[ts-1].y; if(x1*y2>x2*y1)tu[ts++]=node[i]; else ts--,push(i); } void tubao() { tu[0]=node[1]; tu[1]=node[2]; for(int i=3; i<=n; i++)push(i); } void diameter() { int minn,maxx; minn=maxx=0; for(int i=0; i<ts; i++) { if(tu[minn].y>tu[i].y)minn=i; if(tu[maxx].y<tu[i].y)maxx=i; } int s1,s2; s1=minn; s2=maxx; int lens; lens=len(tu[s1],tu[s2]); memset(vis,0,sizeof(vis)); while(vis[s1]==0||vis[s2]==0) { vis[s1]=vis[s2]=1; int x1=tu[s2].x-tu[(s2+1)%ts].x; int x2=tu[(s1+1)%ts].x-tu[s1].x; int y1=tu[s2].y-tu[(s2+1)%ts].y; int y2=tu[(s1+1)%ts].y-tu[s1].y; if(y1*x2<y2*x1)s2=(s2+1)%ts;//根据叉积判断旋转直线最先碰到哪条边 else s1=(s1+1)%ts; lens=max(lens,len(tu[s1],tu[s2])); } cout<<lens<<endl; } int main() { scanf("%d",&n); ts=2; for(int i=1; i<=n; i++)scanf("%d%d",&node[i].x,&node[i].y); sort(node+1,node+n+1,cmp1); sort(node+2,node+n+1,cmp2); tubao(); diameter(); return 0; }
相关文章推荐
- POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
- POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
- 【凸包直径&平面最远点对&对锺点(旋转卡壳)】poj 2187 Beauty Contest
- POJ 2187 旋转卡壳求凸包的直径
- POJ 2187 —— 凸包 + 旋转卡壳 求多边形的直径
- POJ 2187 求多边形直径(凸包+旋转卡壳)
- POJ 2187 Beauty Contest(旋转卡壳求点凸包直径)
- 【POJ 2187】Beauty Contest(凸包直径、旋转卡壳)
- poj 2187 凸包上的直径 - 旋转卡壳
- poj 2187 Beauty Contest , 旋转卡壳求凸包的直径的平方
- poj 2187 Beauty Contest , 旋转卡壳求凸包的直径的平方
- poj 2187 Beauty Contest(二维凸包旋转卡壳)
- POJ 2187 Beauty Contest 凸包+旋转卡壳
- POJ 2187 Beauty Contest 构造凸包 + 旋转卡壳
- poj 2187(凸包+旋转卡壳)
- POJ 2187 Beauty Contest (求最远点对,凸包+旋转卡壳)
- poj2187-Beauty Contest 求凸包最远距离(旋转卡壳算法模板题)
- poj2187——Beauty Contest(凸包+旋转卡壳)
- poj 2187 Beauty Contest(二维凸包旋转卡壳)