'''
思路
旋转卡壳思想配合凸包算法求解最远点对
'''
from typing import List, Tuple
import math
PI = math.acos(-1)
# 两点之间距离的平方
def distance2(a, b):
return (a[0]-b[0])**2 + (a[1]-b[1])**2
# 浮点数的符号函数
ESP = 10 ** (-8)
def sign(val: float):
if abs(val) < ESP:
return 0
return 1 if val > 0 else -1
# 向量的内乘积,表示 |a| * |b| * cos(theta), 输入是两个向量的坐标(x1, y1), (x2, y2)
# 输入是两个向量的坐标(x1, y1), (x2, y2)
def dot(a, b):
return a[0]*b[0] + a[1]*b[1]
# 向量的外乘积,表示两个向量围成的平行四边形面积,b在a逆时针方向,面积为正,否则面积为负
# 输入是两个向量的坐标(x1, y1), (x2, y2)
def cross(a, b):
return a[0]*b[1] - b[0]*a[1]
# 向量取模运算(向量长度)
# 输入参数为(x, y)
def vec_length(v):
return math.sqrt(dot(v, v))
# 求解点到直线的距离
# line_point是直线上的点,line_vec是直线向量,point是待判断的点
def point_line_distance(line_point, line_vec, point):
area = cross( (point[0]-line_point[0], point[1]-line_point[1]), line_vec )
return abs(area / vec_length(line_vec))
class Graham:
# 获取凸包节点函数,get_all_nodes 表示是是否获取凸包边上(共线)所有点,默认只获取凸包的关键点, 输出列表的点是按照逆时针排列的
@staticmethod
def getConvexClosurePoints(points: List[List[float]], get_all_nodes = True) -> List[List[float]]:
if len(points) <= 3:
return points
# 先找y最小面的点,有y值一样的,取x较小者
min_x, min_y = 0x7fffffff, 0x7fffffff
xx, yy = 0x7fffffff, 0x7fffffff
for x, y in points:
if y < min_y:
xx, yy = x, y
min_x, min_y = x, y
elif y == min_y and x < min_x:
xx, yy = x, y
min_x, min_y = x, y
#print(xx, yy)
# 根据逆时针的转角进行排序, 转角一样的,距离短的排在前面
l = [(-(x-xx) / math.sqrt((x-xx)**2 + (y-yy)**2), (x-xx)**2 + (y-yy)**2, x, y) for x, y in points if not (x == xx and y == yy)]
l.sort()
#print(l)
stack = []
stack.append((xx, yy))
stack.append((l[0][2], l[0][3]))
for i in range(1, len(l)):
#print(f'i = {i}')
if len(stack) == 1:
stack.append((l[i][2], l[i][3]))
break
else:
while True:
if len(stack) == 1:
stack.append((l[i][2], l[i][3]))
break
prev_x, prev_y = stack[-1][0] - stack[-2][0], stack[-1][1] - stack[-2][1]
cur_x, cur_y = l[i][2] - stack[-1][0], l[i][3] - stack[-1][1]
# 两个向量的外积
mul = prev_x * cur_y - prev_y * cur_x
if sign(mul) < 0 or (sign(mul) == 0 and get_all_nodes == False):
stack.pop(-1)
else:
stack.append((l[i][2], l[i][3]))
break
return stack
class LongestDisPointPair:
# 求解最远点对的列表[(a1, b1), (a2, b2) ......] a,b 均是点坐标的二元组
@staticmethod
def get_longest_dis_point_pairs(points: List[Tuple]):
pp = Graham.getConvexClosurePoints(points, False)
if len(pp) <= 1:
return 0.0
if len(pp) == 2:
return [(pp[0], pp[1])]
n = len(pp)
pp *= 2
max_dis = -1 # 最远点额距离的平方
ans = []
jj = 2
for ii in range(n):
a, b = pp[ii], pp[ii+1]
v1 = (a[0]-b[0], a[1]-b[1])
last_dis = -1
# 循环一直到点到直线的距离开始下降为止
while jj < 2*n:
dis = point_line_distance(a, v1, pp[jj])
if sign(dis - last_dis) <= 0:
break
last_dis = dis
jj += 1
jj -= 1
dis1, dis2 = distance2(a, pp[jj]), distance2(b, pp[jj])
if sign(dis1 - dis2) < 0:
a, b = b, a
dis1, dis2 = dis2, dis1
sign_val = sign(dis1 - max_dis)
if sign_val > 0:
max_dis = dis1
ans = [(a, pp[jj])]
elif sign_val == 0:
ans.append((a, pp[jj]))
return ans
n = int(input())
points = []
for _ in range(n):
x, y = map(int, input().split())
points.append((x, y))
pairs = LongestDisPointPair.get_longest_dis_point_pairs(points)
print(distance2(pairs[0][0], pairs[0][1]))