# swustoj凸包面积（分治法）

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

#### 样例输出

1.0
0.0

1，找出所有点中x值最小和最大的点就是凸包顶点。

2，以这两点为界将点划分为上包和下包。

3，求上包：每次找离直线最远的点，必是凸包顶点。下包一样求解。

3，递归求解上下包，顺便求面积。

#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;
//求点s3在点s1，s2所连直线的上边，如果满足返回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;
//点s3在点s1,s2z左侧
if ( juge > 0) {
return 1;
}
else if(juge <= 0) {
return 0;
}
}
//求两点直线距离
double getlinedis(node s1, node s2) {
return sqrt(pow(s1.x - s2.x, 2) + pow(s1.y - s2.y, 2));
}
//求三点决定的三角形面积
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为1代表求上包，否则下包
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;
}

int main()
{
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;
}