---
# System prepended metadata

title: biggest triangle (旋轉卡尺)
tags: [codebook]

---

---
tags: codebook
---

# biggest triangle (旋轉卡尺)

convex hull + two pointer

```cpp=
int n; cin >> n;
V<P<double>> v(n);
for (auto& i : v)
	cin >> i.first >> i.second;
sort(v.begin(), v.end());
V<P<double>> s{v[0], v[1]};
auto cross = [&](P<double> p1, P<double> p2, P<double> p3) {
	return (p2.first - p1.first) * (p3.second - p1.second)
	       - (p2.second - p1.second) * (p3.first - p1.first);
};
for (int i = 2; i < n; i++) {
	while (s.size() >= 2 && cross(s.rbegin()[1], s.rbegin()[0], v[i]) <= 0)
		s.pop_back();
	s.push_back(v[i]);
}
for (int i = n - 2, t = s.size() + 1; i >= 0; i--) {
	while (int(s.size()) >= t && cross(s.rbegin()[1], s.rbegin()[0], v[i]) <= 0)
		s.pop_back();
	s.push_back(v[i]);
}
s.pop_back();
auto det = [&](int a, int b, int c) {
	V<V<double>> arr{
		{s[a].first , s[b].first , s[c].first },
		{s[a].second, s[b].second, s[c].second}
	};
	double ret = 0;
	for (int i = 0; i < 3; i++) {
		ret += arr[0][i] * arr[1][(i + 1) % 3];
		ret -= arr[1][i] * arr[0][(i + 1) % 3];
	}
	return ret / 2;
};
double ans = 0;
for (int i = 0, end = s.size(); i < end; i++) {
	for (int j = 1, end = s.size(), k = 2; j < end; j++) {
		while (det(i, j, k) < det(i, j, k + 1)) k++;
		ans = max(ans, det(i, j, k));
	}
}
cout << fixed << setprecision(6) << ans << endl;
```