✨ 新增 0039、0040 题解及配套文档
This commit is contained in:
@@ -6,3 +6,98 @@ If p is the perimeter of a right angle triangle with integral length sides,
|
||||
|
||||
For which value of p<=1000, is the number of solutions maximised?
|
||||
"""
|
||||
|
||||
import time
|
||||
import math
|
||||
|
||||
|
||||
def timer(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
start_time = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
end_time = time.time()
|
||||
print(f"{func.__name__} took time: {end_time - start_time:.6f} seconds")
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
|
||||
def generate_pythagorean_triples(max_perimeter: int = 1000) :
|
||||
"""
|
||||
使用yield生成勾股三元组的m和n参数
|
||||
|
||||
参数:
|
||||
max_perimeter: 三角形周长的最大值
|
||||
|
||||
生成:
|
||||
(m, n) 元组,满足:
|
||||
- m > n > 0
|
||||
- m和n互质 (gcd(m, n) == 1)
|
||||
- m和n一奇一偶
|
||||
- 三角形周长 2*m*(m+n) < max_perimeter
|
||||
"""
|
||||
# 从m=2开始(因为m>n≥1)
|
||||
m = 2
|
||||
|
||||
while True:
|
||||
# 对于每个m,n从1到m-1
|
||||
for n in range(1, m):
|
||||
# 检查是否满足互质条件
|
||||
if math.gcd(m, n) != 1:
|
||||
continue
|
||||
|
||||
# 检查是否一奇一偶
|
||||
if (m % 2) == (n % 2):
|
||||
continue
|
||||
|
||||
# 计算对应三角形的周长
|
||||
perimeter = 2 * m * (m + n)
|
||||
|
||||
# 如果周长超过限制,则停止生成
|
||||
if perimeter >= max_perimeter:
|
||||
# 对于当前m,如果最小周长(当n=1时)已经超过限制,
|
||||
# 那么后续更大的m也会超过,所以完全停止
|
||||
if n == 1:
|
||||
return
|
||||
|
||||
# 如果周长在限制内,则yield当前(m, n)
|
||||
if perimeter < max_perimeter:
|
||||
yield (m, n)
|
||||
|
||||
m += 1
|
||||
|
||||
|
||||
def triangle_length(m:int, n:int) -> int:
|
||||
return 2 * m * (m + n)
|
||||
|
||||
def get_abc(m:int, n:int) -> tuple[int, int, int]:
|
||||
a = m**2 - n**2
|
||||
b = 2 * m * n
|
||||
c = m**2 + n**2
|
||||
return a, b, c
|
||||
|
||||
def primitive_triangles(limit: int = 1000) -> dict[int, list] :
|
||||
triangle_lengths = {}
|
||||
for m, n in generate_pythagorean_triples(limit):
|
||||
length = triangle_length(m, n)
|
||||
if length not in triangle_lengths:
|
||||
triangle_lengths[length] = set()
|
||||
a,b,c = get_abc(m, n)
|
||||
triangle_lengths[length].add((a, b, c))
|
||||
for k in range(2, limit // length + 1) :
|
||||
lenp = k * (a + b + c)
|
||||
if lenp not in triangle_lengths:
|
||||
triangle_lengths[lenp] = set()
|
||||
triangle_lengths[lenp].add((a*k, b*k, c*k))
|
||||
return triangle_lengths
|
||||
|
||||
|
||||
@timer
|
||||
def main():
|
||||
max_perimeter = 1000
|
||||
triangle_lengths = primitive_triangles(max_perimeter)
|
||||
print(triangle_lengths)
|
||||
max_length = max(triangle_lengths, key=lambda x: len(triangle_lengths[x]))
|
||||
print(f"Max length: {max_length}, Count: {len(triangle_lengths[max_length])}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user