poj1113(凸包Graham算法)

来源:互联网 发布:强力数据恢复软件官网 编辑:程序博客网 时间:2024/06/11 00:09
//Graham算法//poj1113此题点坐标为int型#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;#define maxn 1100const 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;}

0 0