对于角度大小的比较,最简单的想法肯定是算出来再比。
但是反三角函数计算可能有误差存在,导致本题神坑数据无法AC……
虽然这题我是用python写的,但实际上不是因为python浮点数运算精度高。
于是我用了比较古老的方法比较角的大小:先按象限比,同一象限再比正切值……
递归调用一次只是为了省略部分代码……
当然,输出角的大小还是得用反三角~
import math
def ang_cmp(x1, y1, x2, y2): #比较两个复数辐角大小的封装函数,当且仅当前一对坐标对应辐角更小时返回True
if y1 < 0 and y2 >= 0: #三四象限的角一定比一二象限大
return False
elif y2 < 0 and y1 >= 0: #同理
return True
elif y1 >= 0 and y2 >= 0: #同在一二象限
if (x1 < 0 and x2 < 0) or (x1 >= 0 and x2 >= 0): #在同一象限
return y1 * x2 < y2 * x1 #正切值的比较,用乘法避免除以0的尴尬
else: #此情况下必为一角在(pi/2,pi]内,另一角在[0,pi/2]内,只需判断前面一对是不是落在第一象限(及坐标轴)的那个
return x1 >= 0
else: #同在三四象限:只需反转到一二象限,交换一下比较顺序即可
return ang_cmp(x2, -y2, x1, -y1)
class vec: #封装需要排序的复数类
def __init__(self, x, y):
self.rel = x
self.img = y
z = complex(x, y)
self.r = float(abs(z)) #计算模长,复数的abs就是模长
if y >= 0:
self.angle = float(math.acos(x/self.r))
else:
self.angle = float(math.pi * 2 - math.acos(x/self.r))
def __lt__(self, other): #python定义类的大小比较的函数,当且仅当self < other时返回True
x1, y1 = self.rel, self.img
x2, y2 = other.rel, other.img
if ang_cmp(x1, y1, x2, y2) or ang_cmp(x2, y2, x1, y1): #两次小于判断相当于不等于的判断
return ang_cmp(x1, y1, x2, y2)
else:
return self.r > other.r
def __str__(self): #定义类与字符串的转换
s = '(%.4f,%.4f)' % (self.r, self.angle)
return s
# main
q = int(input())
for t in range(q):
print("case #%d:" % t)
n = int(input())
ls = list()
for i in range(n):
a, b = map(float, input().split())
ls.append(vec(a, b))
ls.sort()
for i in range(n):
print(ls[i])
这个挺牛批的,至少比我当年写的垃圾代码好多了