竟然还没有讨论,抛砖引玉
话说这个分类讨论是真的繁琐,令人回想起了高中被数学大题支配的恐惧
from math import * from functools import partial eq = partial(isclose, abs_tol=0.00001) class Mt1(BaseException): pass for _ in range(int(input())): t = list(map(float, input().split())) sd, ag = [t[0], t[2], t[4]], [t[1], t[3], t[5]] try: s_c, a_c = 3 - sd.count(-1), 3 - ag.count(-1) if a_c >= 2: # 已知至少两角的情况 assert s_c >= 1 for i, a in enumerate(ag): if a == -1: # 将两角的情况化为三角 ag[i] = pi - sum(ag) - 1 assert eq(sum(ag), pi) for a in ag: assert 0 < a < pi tmp = 0 # 正弦定理求边 for i in range(3): if sd[i] != -1: tmp = sd[i] / sin(ag[i]) for i in range(3): calc = tmp * sin(ag[i]) if sd[i] == -1: sd[i] = calc assert eq(sd[i], calc) else: assert a_c + s_c >= 3 if s_c == 2 and a_c == 1: # 两边一角的情况,化为三边 s_c = 3 i, j = sd.index(-1), 0 while ag[j] == -1: j += 1 if i == j: # 两边及夹角,直接余弦定理化为三边 j, k = (i + 1) % 3, (i + 2) % 3 sd[i] = sqrt(sd[j]**2 + sd[k]**2 - 2 * sd[j] * sd[k] * cos(ag[i])) else: # 两边及对角的情况 k = 3 - i - j tmp = sd[k] * sin(ag[j]) if eq(sd[j], tmp): # 直角三角形的情况 sd[i] = sqrt(sd[k]**2 - sd[j]**2) elif sd[j] < tmp: # 无法构成三角形的情况 raise AssertionError elif sd[j] < sd[k]: # 双解的情况 raise Mt1 else: # 把余弦定理当一元二次方程解出未知边 sd[i] = sd[k] * cos(ag[j]) + sqrt(sd[k]**2 * (cos(ag[j])**2 - 1) + sd[j]**2) if s_c == 3: # 三边的情况 for s in sd: assert s * 2 < sum(sd) for i in range(3): j, k = (i + 1) % 3, (i + 2) % 3 tmp = acos((sd[j]**2 + sd[k]**2 - sd[i]**2) / 2 / sd[j] / sd[k]) if ag[i] == -1: ag[i] = tmp assert eq(ag[i], tmp) except AssertionError: print('Invalid input.') except Mt1: print('More than one solution.') else: print(sd[0], ag[0], sd[1], ag[1], sd[2], ag[2])
竟然还没有讨论,抛砖引玉
话说这个分类讨论是真的繁琐,令人回想起了高中被数学大题支配的恐惧