题目大意:
给 n ( ≤ 5000 ) n(\le 5000) n(≤5000)个点,任意三个点构成的三角形面积不会超过 S ( ≤ 1 0 18 ) S(\le 10^{18}) S(≤1018)
寻找一个顶点都为整点的三角形包含所有顶点,面积不超过 4 S 4S 4S
解题思路:
-
先任意找给定 n n n个点中的三个点 a , b , c a,b,c a,b,c,对于线段 a b ab ab,倘若有其他点 i i i,构成的三角形 △ a b i \triangle abi △abi面积大于 △ a b c \triangle abc △abc,则将 c c c替换,对于其他边同理(这个算法并不是求点集中最大三角形的算法)
-
得到的三角形 △ a b c \triangle abc △abc,最后答案输出 a a a关于 b c bc bc中点对称的点,其余同理,下面初略解释下
-
对于 a , b , c a,b,c a,b,c以外所有的点都会在如下黑线的区域中:
![
- 然后我们可以发现这个大区域是个三角形,且可以用4个与 △ a b c \triangle abc △abc全等的小三角形构成
- 且最终大三角形得到的点,都是上面描述的对称点
AC代码:
#include <bits/stdc++.h>
#define ft first
#define sd second
#define pb push_back
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) //不能跟puts混用
#define seteps(N) fixed << setprecision(N)
#define endl "\n"
const int maxn = 5e3 + 10;
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
const ll mod = 1e9 + 7;
int n;
ll s;
struct Point {
ll x, y;
ll operator ^ (Point p) {return x * p.y - y * p.x;}
Point operator - (Point p) {return {x - p.x, y - p.y};}
} p[maxn];
ll getarea(int i, int j, int k) {
return abs((p[j] - p[i]) ^ (p[k] - p[i]));
}
int main() {
cin >> n >> s;
for (int i = 1; i <= n; i++) cin >> p[i].x >> p[i].y;
int a = 1, b = 2, c = 3;
bool ok = true;
while (ok) {
ok = false;
s = getarea(a, b, c);
for (int i = 1; i <= n; i++) {
if (s < getarea(i, a, b)) ok = true, s = getarea(i, a, b), c = i;
else if (s < getarea(i, b, c)) ok = true, s = getarea(i, b, c), a = i;
else if (s < getarea(i, c, a)) ok = true, s = getarea(i, c, a), b = i;
}
}
cout << p[a].x + p[b].x - p[c].x << " " << p[a].y + p[b].y - p[c].y << endl;
cout << p[b].x + p[c].x - p[a].x << " " << p[b].y + p[c].y - p[a].y << endl;
cout << p[a].x + p[c].x - p[b].x << " " << p[a].y + p[c].y - p[b].y << endl;
return 0;
}