1594. Triangle

CCXXXI_

竟然还没有讨论,抛砖引玉

  • 已知三角一边的情况,直接正弦定理求边(已知两角相当于已知三角)
  • 两边一角的情况,利用余弦定理及各种变式化为三边解决
  • 三边的情况,直接余弦定理求角

话说这个分类讨论是真的繁琐,令人回想起了高中被数学大题支配的恐惧


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])
你当前正在回复 博客/题目
存在问题!