先贴一个模板,方便以后复习。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 1000;
const double eps = 1e-12;
typedef struct
{
double x,y;
}Point;
Point PointSet[maxn],ch[maxn];
int n,len;
double multiply(Point p1,Point p2,Point p0)
{
return ((p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y));
}
double dis(Point p1,Point p2)
{
return (sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)));
}
void Graham_scan(Point PointSet[],Point ch[],int n,int &len)
{
int top = 2,k = 0;
Point tmp;
for(int i = 1;i < n;i++)
{
if((PointSet[i].y < PointSet[k].y) ||
((fabs(PointSet[i].y - PointSet[k].y) < eps) && (PointSet[i].x < PointSet[k].x)))k = i;
tmp = PointSet[0];
PointSet[0] = PointSet[k];
PointSet[k] = tmp;
for(int i = 1;i < n - 1;i++)
{
k = i;
for(int j = i + 1;j < n;j++)
{
if((multiply(PointSet[j],PointSet[k],PointSet[0]) > 0) ||
((fabs(multiply(PointSet[j],PointSet[k],PointSet[0])) < eps) &&
(dis(PointSet[0],PointSet[j]) < dis(PointSet[0],PointSet[k]))))
k = j;
}
if(i != k)
{
tmp = PointSet[i];
PointSet[i] = PointSet[k];
PointSet[k] = tmp;
}
}
ch[0] = PointSet[0];ch[1] = PointSet[1];ch[2] = PointSet[2];
for(int i = 3;i < n;i++)
{
while(multiply(PointSet[i],ch[top],ch[top-1]) >= 0)top--;
ch[++top] = PointSet[i];
}
len = top + 1;
}
}
void init()
{
freopen("Graham-scan.in","r",stdin);
freopen("Graham-scan.out","w",stdout);
}
void solve()
{
n = 5;
double x[] = {0,3,4,2,1};
double y[] = {0,0,0,3,1};
for(int i = 0;i < n;i++)
{
PointSet[i].x = x[i];
PointSet[i].y = y[i];
}
Graham_scan(PointSet,ch,n,len);
for(int i = 0;i < len;i++)
{
cout << ch[i].x << " " << ch[i].y << endl;
}
}
int main()
{
init();
solve();
return 0;
}