1 面积最大的三角形
https://vjudge.net/contest/647024#problem/A
凸包
https://www.cnblogs.com/aiguona/p/7232243.html
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+10;
int n,top;
struct point
{
double x,y;
} p[N], s[N];
/*它是点集的最小凸边界。所有点都在
这个多边形的内部或边界上。
给定一个点集,凸包是包含所有这些点的最小凸多边形
这个三角形的一个或多个顶点在凸包的边界上
给定点集,计算凸包可以显著减少点的数量*/
bool cmp(point a, point b)
{
if (a.x != b.x) return a.x < b.x;
return a.y < b.y;
//按照x,y从小到大排序,升序
//找到凸包的第一个点
}
double cross(point a, point b, point c) //叉积
{
//三角形面积=1/2叉积的绝对值 ,叉积为正,c在ab右侧,a到b转弯到c逆时针,为0三点共线
//凸多边形:对于凸多边形上的任意两点 A 和 B,多边形的边界内的点
//C 必须在AB 的左侧(逆时针方向),保持多边形的凸性。
return (b.x - a.x) *(c.y- a.y) - (c.x- a.x) * (b.y - a.y);
}
signed main()
{
scanf("%lld", &n);
for (int i = 1; i <= n; i++)
scanf("%lf%lf", &p[i].x,&p[i].y);
sort(p +1, p +1 + n,cmp);
//下凸包,模拟栈构造,top栈顶,凸包的点数
top=0;
for(int i=1; i<=n; i++)
{
while (top > 1 && cross(s[top - 1], s[top], p[i]) <= 0) --top ;
s[++top] = p[i];
/*如果叉积值小于或等于 0,说明 p[i] 与当前边的方向不符,可能使当前边向内弯曲,因此需要移除当前边。*/
}
//上凸包
int t = top;
for (int i = n - 1; i >= 1; i -- )
{
while (top > t && cross(s[top - 1], s[top], p[i]) <= 0) --top ;
s[++top] = p[i];
}
n = top - 1;
double ans = 0;
double S = 0;
for (int i = 1; i <= n; i++)
{
int a = i, b=i +1;
for (int j = i + 1; j <= n; j++)
{
while (cross(s[i], s[j], s[a + 1]) < cross (s[i], s[j], s[a])) a = a % n+1;
S = max(S, 0.5 * -cross(s[i], s[j], s[a]));
}
}
printf("%.9lf", S);
}