//分治法求凸包问题
#include<iostream>
#include<vector>
#include<algorithm>
#include<graphics.h>
#include<conio.h>
#include<map>
using namespace std;
const int maxn = 1e5 + 15;
const double eps = 1e-8;
int n = 0;
struct Point {
	double x, y;
}p[maxn], ans[maxn];
int visit[maxn], mark[maxn];
double Djudge(Point a1, Point a2, Point a3) {
	double calculate = a1.x * a2.y + a3.x * a1.y + a2.x * a3.y - a3.x * a2.y - a2.x * a1.y - a1.x * a3.y;
	return calculate;
}
bool cmpxy(const Point a, const Point b) {
	if (a.x != b.x)
		return a.x < b.x;
	else
		return a.y < b.y;
}
void DealLeft(int first, int last) {
	double max = 0;
	int index = -1;
	int i = first;
	if (first < last) {
		for (i = first + 1; i < last; i++){
			double calcu = Djudge(p[first], p[i], p[last]);
			if (calcu == 0) { visit[i] = 1; }
			if (calcu > max) {
				max = calcu;
				index = i;
			}

		}
	}
	else {
		for (i - 1; i > last; i--) {
			double calcu = Djudge(p[first], p[i], p[last]);
			if (calcu == 0) { visit[i] = 1; } //
			if (calcu > max) {
				max = calcu;
				index = i;
			}
		}
	}
	if (index != -1) {
		visit[index] = 1; 
		DealLeft(first, index);
		DealLeft(index, last);
	}
}
//点点,将所有点画在坐标轴上
void drow_graph(vector<pair<double, double> >& point, int n) {
	initgraph(800, 800);
	setbkcolor(WHITE);
	cleardevice();
	setlinecolor(BLUE);
	line(400, 0, 400, 800);
	line(0, 400, 800, 400);
	for (int i = 0; i < n; i++) {
		setfillcolor(RED);
		int x = point[i].first + 400;
		int y = 400 - point[i].second;
		fillcircle(x, y, 5);
	}
}

//连线,将所有点连起来
void connect_end(Point* point, int n) {
	setlinecolor(RED);
	setlinestyle(10);
	for (int i = 0; i < n - 1; i++) {
		int x1 = point[i].x + 400;
		int y1 = 400 - point[i].y;
		int x2 = point[i + 1].x + 400;
		int y2 = 400 - point[i + 1].y;
		line(x1, y1, x2, y2);
	}
	int x = point[0].x + 400;
	int y = 400 - point[0].y;
	int x1 = point[n - 1].x + 400;
	int y1 = 400 - point[n - 1].y;
	line(x, y, x1, y1);
	_getch();
	closegraph();
}
int dblcmp(double k) {
	if (fabs(k) < eps) return 0;
	return k > 0 ? 1 : -1;
}
double multi(Point p0, Point p1, Point p2) {
	return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}
bool cmp(const Point& a, const Point& b) {
	return dblcmp(multi(ans[0], a, b)) > 0;
}
int main()
{
	vector<pair<double, double> > pointsArray(maxn);
	cout << "请输入点的个数:";
	cin >> n;
	cout << "请输入点的坐标:" << endl;
	for (int i = 0; i < n; i++) {
		cin >> p[i].x >> p[i].y;
		visit[i] = 0;
		pointsArray[i] = make_pair(p[i].x, p[i].y);
	}
	drow_graph(pointsArray, n);
	visit[0] = 1;
	visit[n - 1] = 1;
	sort(p, p + n, cmpxy);
	DealLeft(0, n - 1); 
	DealLeft(n - 1, 0); 
	int t = 0;
	for (int i = 0; i < n; i++) {
		if (visit[i] == 1) {
			ans[t].x = p[i].x;
			ans[t].y = p[i].y;
			t++;
		}
	}
	sort(ans + 1, ans + t, cmp);
	connect_end(ans, t);
	return 0;
}