[KOI 2025 #1] 直角等腰三角形
子问题 3
作为答案的直角等腰三角形,可以分为其直角顶点位于斜边上方和下方两种情况。对每种情况分别计算斜边长度的最小值,然后输出两者中较小的值即可。
我们设连接直角等腰三角形斜边的两个端点为
设一个直角等腰三角形的斜边端点为
利用上述条件,我们可以在
子问题 4
可以发现,满足条件且斜边长度最小的直角等腰三角形,其每条边上都至少包含一个给定的点。(可以认为,这也包括了边的端点恰好是给定点之一的情况。)
我们先只考虑直角顶点在斜边上方的情况。如果我们在直角等腰三角形的每条边上各选一个点,就可以确定该三角形的三个顶点。因此,对于选择三个点的
总时间复杂度为
子问题 5
在此子问题中,所有给定点的
子问题 6
在此子问题中,所有给定点都位于直线
子问题 7
我们先只考虑直角顶点在斜边上方的情况。
假设作为答案的直角等腰三角形,其斜边的右端点坐标为
如果一个斜边长度为
因为需要求斜边长度的最小值,所以可以通过对
用同样的方法,也可以求出直角顶点在斜边下方情况时斜边长度的最小值。如果两种情况都可行,则输出两个斜边长度中较小的一个;如果只有一种情况可行,则输出该情况下的斜边长度。
子问题 8
我们只考虑直角顶点在斜边上方的情况。在这类三角形中,我们设斜边长度最小的三角形,其斜边的两个端点为
设所有给定点的
由于
直角顶点在斜边下方的情况,也可以用同样的方法解决。
总时间复杂度为
/*
* 2025 KOI 抗急
* 檬殿何 2锅
*/
#include <bits/stdc++.h>
using namespace std;
#define MAX 100'010
int X[100'010];
int Y[100'010];
signed main() {
ios::sync_with_stdio(false), cin.tie(0);
int N;
cin >> N;
int i;
int minY = 2e9, maxY = -2e9;
for (i = 1; i <= N; i++) {
cin >> X[i] >> Y[i];
minY = min(minY, Y[i]);
maxY = max(maxY, Y[i]);
}
int ans = 2e9;
int minv = 2e9, maxv = -2e9;
for (i = 1; i <= N; i++) {
maxv = max(maxv, X[i] + Y[i]);
minv = min(minv, X[i] - Y[i]);
}
ans = min(ans, (maxv - minY) - (minY + minv));
minv = 2e9, maxv = -2e9;
for (i = 1; i <= N; i++) {
maxv = max(maxv, X[i] - Y[i]);
minv = min(minv, X[i] + Y[i]);
}
ans = min(ans, (maxY + maxv) - (minv - maxY));
cout << ans;
}