我的心愿是世界和平!
极角排序 –叉积
方便而且好理解,建议使用。
以p[0]为原点。
int cmp(point a,point b)
{
if((a.x-p[0].x)*(b.y-p[0].y)-(b.x-p[0].x)*(a.y-p[0].y)==0)//计算叉积.
return a.x<b.x;
else
return (a.x-p[0].x)*(b.y-p[0].y)-(b.x-p[0].x)*(a.y-p[0].y)>0;
}
sort(p+1,p+m,cmp);
极角排序–atan2()
以p[0]为原点。
int cmp(point a,point b)
{
if(atan2(a.y-p[0].y,a.x-p[0].x)!=atan2(b.y-p[0].y,b.x-p[0].x))
return atan2(a.y-p[0].y,a.x-p[0].x)<atan2(b.y-p[0].y,b.x-p[0].x);
else return (a.x-p[0].x)<(b.x-p[0].x);
}
sort(p+1,p+m,cmp);
极角排序–象限
以(0,0)为原点。
int Quadrant(point a) //象限排序,注意包含四个坐标轴
{
if(a.x>0&&a.y>=0) return 1;
if(a.x<=0&&a.y>0) return 2;
if(a.x<0&&a.y<=0) return 3;
if(a.x>=0&&a.y<0) return 4;
}
int cmp(point a,point b) //先按象限从小到大排序 再按极角从小到大排序
{
if(Quadrant(a)==Quadrant(b))//返回值就是象限
return cmp1(a,b);
else Quadrant(a)<Quadrant(b);
}
sort(p,p+m,cmp);
极角排序–complex
表示不太懂。
#include<complex>
#define x real()
#define y imag()
#include<algorithm>
using namespace std;
int cmp(const Point& p1, const Point& p2)
{
return arg(p1) < arg(p2);
}
凸包
Graham扫描法。
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
struct point
{
int x;
int y;
} p[1010],tu[1010],t;
int cmp(point a,point b)
{
if((a.x-p[0].x)*(b.y-p[0].y)-(b.x-p[0].x)*(a.y-p[0].y)==0)//若两点极角相同,x更小的在前.
return a.x<b.x;
else
return (a.x-p[0].x)*(b.y-p[0].y)-(b.x-p[0].x)*(a.y-p[0].y)>0;//叉积值为正,b点在a点左侧.
}
int tubao(point c,point a,point b)
{
if((a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y)<0)//如果叉积值为负,b点在a点右侧.
return -1;
return 1;
}
double edge(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
int m,i;
scanf("%d",&m);//接下来有多少个点.
for(i=0; i<m; i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
if(p[i].y<p[0].y)//在y值最小的前提下,将x值最小的点移到p[0]处.
{
t=p[0];
p[0]=p[i];
p[i]=t;
}
else if(p[i].y==p[0].y)
{
t=p[0];
p[0]=p[i];
p[i]=t;
}
}
sort(p+1,p+m,cmp);//极角排序.
int top=1;
tu[0]=p[0];
tu[1]=p[1];
for(i=2; i<m;)
{
if(tubao(tu[top-1],tu[top],p[i])<0)
{
top--;
if(top==0)
{
top++;
tu[top]=p[i];
i++;
}
}
else
{
top++;
tu[top]=p[i];
i++;
}
}
double sum=0;
for(i=0; i<top; i++)
{
sum+=edge(tu[i],tu[i+1]);
}
sum+=edge(tu[0],tu[top]);
printf("%.2lf",sum);
return 0;
}
其他解法:九茶优快云 http://blog.youkuaiyun.com/bone_ace/article/details/46239187