之前牛客遇到旋转卡壳,就自己写板子存下来了,但是这道题拿出来WA#6(就是上边那些测试点第一个),弄了很久也没明白哪错了,让gpt写了一份和我WA一个点,没办法了来求助大神,代码如下:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
typedef struct dian {
i64 x;
i64 y;
} Dian;
// 叉积函数,用于计算a-b和b-c两向量的叉积
i64 cross(Dian a, Dian b, Dian c) {
i64 x2 = c.x - a.x, x1 = b.x - a.x, y1 = b.y - a.y, y2 = c.y - a.y;
return x1 * y2 - y1 * x2;
}
// 计算两点间距离的平方
i64 res(Dian a, Dian b) {
i64 x1 = b.x - a.x, y1 = b.y - a.y;
return x1 * x1 + y1 * y1; // 返回两个点之间的平方距离
}
// 凸包构建算法,返回凸包点的数量
Dian* tubao(Dian a[], i64 &n) {
i64 dd = 1;
// 找到 y 最小的点作为基准点
for (i64 i = 2; i <= n; i++) {
if (a[i].y < a[dd].y || (a[i].y == a[dd].y && a[i].x < a[dd].x)) {
dd = i;
}
}
// 基准点放在a[1]位置
swap(a[1], a[dd]);
// 极角排序,按基准点与其他点的相对极角排序
sort(a + 2, a + n + 1, [&](const Dian& p1, const Dian& p2) {
i64 c = cross(a[1], p1, p2);
if (c == 0) {
return res(a[1], p1) < res(a[1], p2); // 共线时按距离排序
}
return c > 0; // 否则按极角排序
});
Dian* tb = (Dian*)malloc((n + 10) * sizeof(Dian));
// 构建凸包,直接在数组a上操作,返回凸包的点数
i64 t = 1; // 初始化凸包点数为1(即基准点a[1]已经是凸包的一部分)
tb[1]=a[1];
for (i64 i = 2; i <= n; i++) {
while (t > 1 && cross(tb[t - 1], tb[t], a[i]) <= 0) t--; // 保证凸性
tb[++t] = a[i];
}
n=t;
return tb; // 返回凸包的点数
}
// 旋转卡壳算法,找到凸包的最大直径平方
i64 xzkk(Dian a[], i64 n) {
i64 zj = 0;
for (i64 i = 1, j = 2; i <= n; i++) {
while (res(a[i], a[j]) < res(a[i], a[j % n + 1])) j = j % n + 1;
zj = max(zj, res(a[i], a[j])); // 找到最大直径的平方
}
return zj;
}
void solve()
{
Dian a[50505];
i64 n;
cin>>n;
for(i64 i=1;i<=n;i++){
cin>>a[i].x>>a[i].y;
}
if (n == 1) {
cout << 0 << endl;
return;
} else if (n == 2) {
cout << res(a[1], a[2]) << endl;
return;
}
Dian* aa=tubao(a,n);
cout<<xzkk(aa,n);
}
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(nullptr);
// cout.tie(nullptr);
i64 T = 1;
//cin >> T;
while (T--)
solve();
return 0;
}
(PS:经过一位一位测试,那个点答案是100000000,我输出的是99999605,,不过似乎知道了也没用呜呜呜。)