#include <bits/stdc++.h>
namespace geometry {
#include<vector>
#include<algorithm>
using namespace std;
double inf=(double)1e15,eps=(double)0;
struct Vector { //向量
double x, y;
};
struct Point { //点
double x, y;
};
struct Segment { //线段
Point a, b;
};
struct Line { //直线
Point a;
Vector k;
};
struct Polygon { //多边形
vector<Point> a;
};
double chk(double n) { return (n > eps ? 1 : (n < -eps ? -1 : 0)); }
double fbs(double n) { return n * chk(n); }
double distance2(Point a, Point b) { return (b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y); }
double distance(Point a, Point b) { return sqrt(distance2(a,b)); }
double operator*(Vector q, Vector h) { return q.x * h.x + q.y * h.y; }
Vector operator*(Vector q, double h) { return (Vector){ q.x * h, q.y * h }; }
Vector operator*(double q, Vector h) { return (Vector){ q * h.x, q * h.y }; }
Vector operator+(Vector q, Vector h) { return (Vector){ q.x + h.x, q.y + h.y }; }
Point operator+(Point q, Vector h) { return (Point){ q.x + h.x, q.y + h.y }; }
Point operator-(Point q, Vector h) { return (Point){ q.x - h.x, q.y - h.y }; }
Vector operator-(Point q, Point h) { return (Vector){ h.x - q.x, h.y - q.y }; } // q-h,得到q->h的向量
double operator^(Vector q, Vector h) { return q.x * h.y - q.y * h.x; }
bool operator ==(Vector q,Vector h) { return chk(q.x-h.x)==0&&chk(q.y-h.y)==0;}
bool operator ==(Point q,Point h) { return chk(q.x-h.x)==0&&chk(q.y-h.y)==0;}
bool operator ==(Segment q,Segment h) { return q.a==h.a&&q.b==h.b||q.a==h.b&&q.b==h.a;}
bool operator ==(Line q,Line h) { return chk(q.k^h.k)==0&&(chk(q.k^(q.a-h.a))==0||q.a==h.a);}
bool operator !=(Vector q,Vector h) { return !(q==h);}
bool operator !=(Point q,Point h) { return !(q==h);}
bool operator !=(Segment q,Segment h) { return !(q==h);}
bool operator !=(Line q,Line h) { return !(q==h);}
bool turn_left(Vector q, Vector h) { return chk(q ^ h) > 0; }
bool turn_right(Vector q, Vector h) { return chk(q ^ h) < 0; }
bool turn_back(Vector q, Vector h) { return chk(q * h) < 0; }
bool vertical(Vector q, Vector h) { return chk(q * h) == 0; }
bool line_cross_check(Line a, Line b) { return chk(a.k^b.k)==0; }
bool point_on_line(Point a, Line b) { return chk((b.a - a) ^ b.k) == 0; }
int point_on_segment(Segment a,Point b) {
if(b==a.a||b==a.b)
return 2;
return chk((a.a - b) ^ (a.b - b)) == 0 && chk((a.a - b) * (a.b - b));
}
int segment_cross_check(Segment a, Segment b) {
if(a==b)
return 3;
if(a.a==b.a||a.a==b.b||a.b==b.a||a.b==b.b)
return 2;
if (chk(min(a.a.x, a.b.x) - max(b.a.x, b.b.x))>0 || chk(min(a.a.y, a.b.y) - max(b.a.y, b.b.y))>0 ||
chk(min(b.a.x, b.b.x) - max(a.a.x, a.b.x))>0 || chk(min(b.a.y, b.b.y) - max(a.a.y, a.b.y))>0)
return false;
double ans1 = chk((a.a - a.b) ^ (b.a - a.a)), ans2 = chk((a.a - a.b) ^ (b.b - a.a)),
ans3 = chk((b.a - b.b) ^ (a.a - b.a)), ans4 = chk((b.a - b.b) ^ (a.b - b.a));
return ans1 != ans2 && ans3 != ans4 || ans1 == 0;
}
Point line_cross_get_intersection(Line a, Line b) {
Vector c = b.a - a.a;
return a.a - (b.k ^ c) / (b.k ^ a.k) * a.k;
}
Point foot_point(Point a, Line b) { return b.a - b.k * (b.k * (a - b.a) / (b.k * b.k)); }
Point symmetric_point(Point a, Line b) {
Point c = foot_point(a, b);
return a + 2 * (a - c);
}
double distance_point_to_line(Point a, Line b) {
Vector c = b.a - a;
return fabs((c ^ b.k) / distance(b.a, b.a + b.k));
}
double distance_point_to_segment(Point a, Segment b) {
if (chk((b.a - b.b) * (b.b - a)) == chk((b.b - b.a) * (b.a - a)))
return distance_point_to_line(a, (Line){ b.a, (b.b - b.a) });
else
return min(distance(a, b.a), distance(a, b.b));
}
double area_of_polygon(Polygon a) {
double value = 0;
for (int i = 1; i < a.a.size(); i++)
value = value + ((Vector){ a.a[i - 1].x, a.a[i - 1].y } ^ (Vector){ a.a[i].x, a.a[i].y });
value = value + ((Vector){ a.a[a.a.size() - 1].x, a.a[a.a.size() - 1].y } ^ (Vector){ a.a[0].x, a.a[0].y });
return value / 2.0 * chk(value);
}
int point_in_polygon(Polygon a,Point b){
for(int i=1;i<a.a.size();i++)
if(point_on_segment((Segment){a.a[i-1],a.a[i]},b)>0)
return 2;
if(point_on_segment((Segment){a.a[0],a.a[a.a.size()-1]},b)>0)
return 2;
int value=0;
Segment c=(Segment){-inf,b.y};
for(int i=1;i<a.a.size();i++)
if(segment_cross_check((Segment){a.a[i-1],a.a[i]},c)==1)
value++;
if(segment_cross_check((Segment){a.a[0],a.a[a.a.size()-1]},c)==1)
value++;
return (value&1);
}
Polygon graham(vector<Point> a){
Point O=a[0];
int O_id=0;
for(int i=1;i<a.size();i++)
if(a[i].y<O.y){
O=a[i];
O_id=i;
}
else if(a[i].y==O.y&&a[i].x<O.x){
O=a[i];
O_id=i;
}
swap(a[0],a[O_id]);
sort(a.begin()+1,a.end(),[&](Point q,Point h)->bool{return chk((O-q)^(O-h))==1?true:(chk((O-q)^(O-h))==-1?false:(q.x!=h.x?q.x<h.x:q.y<h.y));});
Polygon ans;
ans.a.push_back(a[0]);
for(int i=1;i<a.size();i++){
while(ans.a.size()>1&&chk((ans.a[ans.a.size()-2]-ans.a[ans.a.size()-1])^(ans.a[ans.a.size()-1]-a[i]))!=1)
ans.a.pop_back();
ans.a.push_back(a[i]);
}
return ans;
}
Polygon andrew(vector<Point> a)
{
sort(a.begin(),a.end(),[&](Point q,Point h)->bool{if(q.x!=h.x)return q.x<h.x;return q.y<h.y;});
Polygon ans;
ans.a.push_back(a[0]);
for(int i=1;i<a.size();i++){
while(ans.a.size()>1&&chk((ans.a[ans.a.size()-2]-ans.a[ans.a.size()-1])^(ans.a[ans.a.size()-1]-a[i]))==-1)
ans.a.pop_back();
ans.a.push_back(a[i]);
}
for(int i=a.size()-1;i>=0;i--){
while(ans.a.size()>1&&chk((ans.a[ans.a.size()-2]-ans.a[ans.a.size()-1])^(ans.a[ans.a.size()-1]-a[i]))==-1)
ans.a.pop_back();
ans.a.push_back(a[i]);
}
ans.a.pop_back();
return ans;
}
double roating_calipers(Polygon a){
if(a.a.size()==2)
return distance2(a.a[0],a.a[1]);
double ans=0;
int j=2;
a.a.push_back(a.a[0]);
for(int i=0;i<a.a.size()-1;i++){
Point now1=a.a[i],now2=a.a[i+1];
ans=max(ans,distance2(now1,now2));
while(fbs((a.a[j]-now1)^(a.a[j]-now2))<fbs((a.a[j+1]-now1)^(a.a[j+1]-now2))){
j=j+1;
if(j==a.a.size()-1)
j=0;
}
ans=max(ans,max(distance2(now1,a.a[j]),distance2(now2,a.a[j])));
}
return ans;
}
}
using namespace geometry;
int main() {
int n;
vector<Point> input;
cin>>n;
for(int i=1;i<=n;i++){
Point now;
cin>>now.x>>now.y;
input.push_back(now);
}
cout<<(long long)roating_calipers(graham(input));
return 0;
}
不知道为什么无法通过 hack #3,求数据