//Graham算法 //poj1113此题点坐标为int型 #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define maxn 1100 const double pi=acos(-1.0); struct Point{ int x,y; }s[maxn]; int st[maxn],top; int cross(Point p,Point p1,Point p2) { return (p1.x-p.x)*(p2.y-p.y)-(p2.x-p.x)*(p1.y-p.y); } double dist(Point p1,Point p2) { double tmp=(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y); return sqrt(tmp); } bool cmp(Point p1,Point p2) //取s[0]作为极点,极角排序,角度相同则距离小的优先 { int tmp=cross(s[0],p1,p2); if(tmp>0) return true; else if(tmp==0&&dist(s[0],p1)<dist(s[0],p2)) return true; else return false; } void Graham(int n) { if(n==1) { top=0; st[0]=0;} if(n==2) { top=1; st[0]=0; st[1]=1;} if(n>2) { int i; st[0]=0,st[1]=1; //先进去两个点 top=1; for(i=2;i<n;i++) { while(top>0&&cross(s[st[top-1]],s[st[top]],s[i])<0) top--; st[++top]=i; } } } int main() { int n,l; cin>>n>>l; Point p0; scanf("%d%d",&s[0].x,&s[0].y); p0.x=s[0].x,p0.y=s[0].y; int k=0; for(int i=1;i<n;i++) { scanf("%d%d",&s[i].x,&s[i].y); if((p0.y>s[i].y)||(p0.y==s[i].y&&p0.x>s[i].x)) //找到最左下的点作为起点 { p0.x=s[i].x; p0.y=s[i].y; k=i; } } s[k]=s[0]; //将最左下的点与第一个点交换 s[0]=p0; sort(s+1,s+n,cmp); Graham(n); double re=0; for(int i=0;i<top;i++) { re+=dist(s[st[i]],s[st[i+1]]); } re+=dist(s[st[0]],s[st[top]]); re+=2*pi*l; printf("%.0f\n",re); return 0; }
poj1113(凸包Graham算法)
猜你喜欢
转载自blog.csdn.net/zizahn/article/details/52750162
今日推荐
周排行