⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 凸包.cpp

📁 各种算法
💻 CPP
字号:
//convex hull algorithm of Graham
#include"iostream"
#include"stdio.h"
//#include"stdlib.h"
#include"math.h"
#include"algorithm"
#include"stack"
using namespace std;
#define N 1002
#define INF (unsigned int)(-1)>>1
#define PI 3.1415926

typedef struct TPoint
{
    double x;
    double y;
    //double z;
	TPoint(){}
	TPoint(double a,double b){x = a; y = b;}
}TPoint;	
TPoint v[N];
int n;int r;					// 3<=n<=1000
enum orientation{ _left = -1,straight = 0,_right = 1};

int cross(TPoint m,TPoint n)
{
	if(n.x*m.y - m.x*n.y > 0) return _right;
	else if (n.x*m.y - m.x*n.y == 0) return straight;
	else return _left;
}
int direction(TPoint a,TPoint b,TPoint c)//Cross Funtion 叉积
{	TPoint m,n;
	m.x = b.x - a.x;
	m.y = b.y - a.y;
	n.x = c.x - a.x;
	n.y = c.y - a.y;
	return cross(m,n);
}
bool cmp(TPoint a,TPoint b)
{	
	TPoint o = v[0];
	TPoint c,d;
	c.x = a.x-o.x;
	d.x = b.x-o.x;
	c.y = a.y-o.y;
	d.y = b.y-o.y;
	if(cross(c,d) == _right) return true;
	else if (cross(c,d) == straight){
		if(c.x*c.x+c.y*c.y - (d.x*d.x+d.y*d.y)<0) return true;
		else return false;
	}
	else return false;
}
void Sort()//求逆时针扇形阵列
{	
	for(int i = 1; i < n; i++) //find start point
		if(v[i].y < v[0].y||(v[i].y == v[0].y && v[i].x < v[0].x))
			swap(v[i],v[0]);
	sort(v+1,v+n,cmp);
}
stack<TPoint>Graham()
{	
	stack<TPoint>st;	
	TPoint tmp = v[1]; v[n] = v[0];
	st.push(v[0]);
	for(int i = 2;i <= n;i++){
		while(direction(st.top(),tmp,v[i]) == _left){
			tmp = st.top(); st.pop();
		}
		if(direction(st.top(),tmp,v[i]) == _right) st.push(tmp); // =0 斜率相同 排除		
		tmp = v[i];
	}
	return st;
}
double length(TPoint p,TPoint q)
{	return sqrt(pow(p.x-q.x,2)+pow(p.y-q.y,2));
}
bool input()
{	
	if(scanf("%d%d",&n,&r) == EOF) return false;
	for(int i = 0;i < n;i++) scanf("%lf%lf",&v[i].x,&v[i].y);
	return true;
}
double circumference(stack<TPoint>st)
{	
	double sum = 0;
	TPoint head = st.top();
	TPoint p = head; st.pop();
	while(!st.empty())
	{	//printf("(%.1f,%.1f)\n",p.x,p.y);
		TPoint q = st.top();
		sum += length(p,q);
		st.pop(); p = q;
	}
	sum += length(head,p) + PI * 2 * r;
	return sum;
}
int main()
{	freopen("in.txt","r",stdin);
	while(input()) {
		Sort();
		stack<TPoint>st = Graham();	
		printf("%.0lf\n",circumference(st));
	}
	return 1;
}

/*
7 7
0 0
1 1
4 4
2 2
3 3
2 4
0 5
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -