swustoj convex hull area (divide and conquer)

McDull is a naughty boy. One day he spilled ink on the white wall while playing with the pen. After a while, McDull's mother will come back, McDull wanted to cover the ink dots on the wall with a white convex polygon in order to keep his mother from knowing about it. Can you tell McDull what minimum convex polygon area is needed to cover the dots? Now, given the coordinates of these ink dots, please help McDull calculate the area of ​​the smallest convex polygon that covers these ink dots.

enter

Multiple sets of test data. The first line is an integer T, indicating that there are a total of T groups of test data.
The first line of each set of test data is a positive integer N (0 < N <= 105), indicating the number of ink dots. The next N lines each contain two integers Xi and Yi (0<=Xi, Yi<=2000), representing the coordinates of each ink dot. Each line may contain multiple spaces between coordinates.

output

Each line outputs the results of a set of test data, just output the area of ​​the smallest convex polygon. The area is a real number, and only one digit after the decimal point is required, and no extra spaces are required.

sample input

2
4
0 0
1 0
0 1
1 1
2
0 0
0 1

Sample output

1.0
0.0

Problem Solving: Divide and Conquer.

1. Find the point with the smallest and largest x value among all the points, which is the vertex of the convex hull.

2. Divide the points into upper and lower packets with these two points as the boundary.

3. Find the upper hull: Every time you find the point farthest from the straight line, it must be the vertex of the convex hull. Solve the same as the next package.

3. Recursively solve the upper and lower packages, and by the way find the area.


#include<iostream>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<map>
#include<string>
#include<stdio.h>
#include<vector>
#include<stack>
using namespace std;
struct node {
	int x, y;
}s[105];
vector<node>ans;
vector<int>::iterator it;
double ansans;
// Find point s3 on the top of the line connected by points s1 and s2, if it is satisfied, return true
bool isup (node ​​s1, node s2, node s3) {
	swap(s1, s2);
	int juge = s1.x*s2.y + s3.x*s1.y + s2.x*s3.y - s3.x*s2.y - s2.x*s1.y - s1.x*s3.y ;
	//Point s3 is to the left of point s1, s2z
	if ( juge > 0) {
		return 1;
	}
	else if(juge <= 0) {
		return 0;
	}
}
// find the distance between two points
double getlinedis(node s1, node s2) {
	return sqrt(pow(s1.x - s2.x, 2) + pow(s1.y - s2.y, 2));
}
// Find the area of ​​the triangle determined by the three points
double getdis(node s1, node s2, node s3) {
	double a = getlinedis(s1, s2);
	double b = getlinedis(s1, s3);
	double c = getlinedis(s2, s3);
	double p = (a + b + c) / 2;
	return sqrt(p * (p - a)*(p - b)*(p - c));
}
//isupdp is 1 to ask for the package, otherwise the package
void getup(node s1, node s2, vector<node>up,bool isupdp) {
	node temp;
	double _max = 0;
	double maxs = 0;
	for (int i = 0;i < up.size();i++) {
		double dis = getdis(s1, s2, up[i]);
		bool tt = isup(s1, s2, up[i]);
		if (!isupdp) {
			tt =! tt;
		}
		if (tt) {
			if (dis > _max) {
				_max = dis;
				maxs = dis;
				temp = up[i];
			}
		}
		else {
			if(up[i].x)
			up.erase(up.begin()+i);
			if (i != 0) {
				i--;
			}
		}
	}
	ans.push_back(temp);
	ansans += maxs;
	if (up.size() > 1) {
		getup(s1, temp, up,isupdp);
		getup(temp, s2, up, isupdp);
	}
}

bool cmp(node a, node b) {
	return a.y < b.y;
}

intmain()
{
	int t;
	cin >> t;

	while (t--) {
		vector<node>v;
		int n;
		cin >> n;
		int _minid, _maxid;
		_minid = 0;
		_maxid = 0;
		for (int i = 0;i < n;i++) {
			scanf("%d%d", &s[i].x, &s[i].y);
			v.push_back(s[i]);
			if (s[_maxid].x > s[i].x) {
				_maxid = i;
			}
			if (s[_minid].x < s[i].x) {
				_minid = i;
			}
		}
		vector<node>up, down;
		for (int i = 0;i < n;i++) {
			if (i != _minid && i != _maxid) {
				if (isup(s[_minid], s[_maxid], s[i])) {
					up.push_back(s[i]);
				}
				else {
					down.push_back(s[i]);
				}
			}
		}
		ans.push_back(s[_minid]);
		ans.push_back(s[_maxid]);
		getup(s[_minid], s[_maxid], up, 1);
		getup(s[_minid], s[_maxid], down, 0);
		sort(ans.begin(), ans.end(), cmp);
		printf("%.1lf\n", ansans);
		ansans = 0;
	}
	return 0;
}



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325668600&siteId=291194637
Recommended