把O2优化关了就AC了
我也不知道具体啥问题
以下是我的代码
#include <bits/stdc++.h>
using namespace std;
#define MAXN 50005
typedef long long ll;
struct Point
{
ll x, y;
Point(ll _x = 0, ll _y = 0)
{
x = _x, y = _y;
}
Point operator-(Point const &next) const
{
Point res(x - next.x, y - next.y);
return res;
}
ll operator*(Point const &next) const
{
return x * next.y - y * next.x;
}
bool operator==(Point const &next) const
{
return x == next.x && y == next.y;
}
}p[MAXN], h[MAXN]; // p存储点或向量
int stk[MAXN]; // stk存的是下标,用数组实现栈
bool used[MAXN]; // used[i]表示下标i对应的点在不在凸包上
int tp, n, ans;
ll dis(Point a, Point b)
{
ll dx = (a.x - b.x) * (a.x - b.x);
ll dy = (a.y - b.y) * (a.y - b.y);
return dx + dy;
}
double sumdis()
{
double res = 0;
for (int i = 1; i <= ans; i++)
{
res += dis(h[i], h[i + 1]);
}
return res;
}
bool cmp1(Point const &mext, Point const &next)
{
return (mext.x < next.x) || (mext.x == next.x && mext.y < next.y);
}
// Andrew算法
void Andrew()
{
tp = 0; // 初始化栈
memset(used, 0, sizeof(used));
memset(stk, 0, sizeof(stk));
sort(p + 1, p + 1 + n, cmp1);
stk[++tp] = 1;
for (int i = 2; i <= n; i++)
{
//下凸包顺序遍历,有右转就右转
while (tp >= 2 && (p[stk[tp]] - p[stk[tp-1]]) * (p[i] - p[stk[tp]]) <= 0)
used[stk[tp--]] = 0; // 弹出栈顶
used[i] = 1; // 记录新点
stk[++tp] = i; // 新点入栈
}
int tmp = tp; // tmp表示下凸包大小
for (int i = n - 1; i > 0; i--)
{
// 上凸包逆序遍历,有右转就右转
if (!used[i])
{
while (tp > tmp && (p[stk[tp]] - p[stk[tp-1]]) * (p[i] - p[stk[tp]]) <= 0)
used[stk[tp--]] = 0;
used[i] = 1;
stk[++tp] = i;
}
}
for (int i = 1; i <= tp; i++)
{
h[i] = p[stk[i]]; // h以1号点开始,以1号点结束
}
ans = tp - 1; // ans表示凸包的点的实际数量
}
/*
* 旋转卡壳法(旋转卡尺)
* 枚举凸包的边,同时维护其他需要的点
* 可求解凸包直径,最小矩形覆盖,最大面积等
*
* 根据我们枚举的边,可以从每个维护的点画出一条或平行或垂直的直线,
* 为了确保对于当前枚举的边的最优性,我们的任务就是使这些直线能将
* 凸包正好卡住。而边通常是按照向某一方向旋转的顺序来枚举,所以整
* 个过程就是在边「旋转」,边「卡壳」。
*/
ll square(Point a, Point b, Point c)
{
// 三角形面积
return abs((c - a) * (b - a));
}
ll get_longest()
{
ll res;
int j = 3;
if (ans <= 1) return 0;
if (ans == 2) return dis(h[1], h[2]);
// 枚举边h[i]h[i+1]
for (int i = 1; i <= ans; i++)
{
if (h[i] == h[i+1]) continue;
while (square(h[i], h[i+1], h[j]) <= square(h[i], h[i+1], h[j%ans+1]))
j = j % tp + 1;
res = max({res, dis(h[i], h[j]), dis(h[i+1], h[j])});
}
return res;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> p[i].x >> p[i].y;
}
Andrew();
cout << get_longest() << endl;
}