Graham-scan模板

先贴一个模板,方便以后复习。

#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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值