3 回答
TA贡献1777条经验 获得超3个赞
在您的算法中,您正在搜索所有可能的 y 值。这是不必要的。这里的诀窍是要意识到
y^2 + x^2 = 2n^2
直接意味着
y^2 = 2n^2-x^2
所以这意味着你只需要检查 2n^2-x^2 是一个完美的正方形。你可以这样做
y2 = 2*n*n - x*x
#check for perfect square
y = math.sqrt(y2)
if int(y + 0.5) ** 2 == y2:
#We have a perfect square.
此外,在您的算法中,您只检查不超过 n 的 x 值。这是不正确的。由于 y^2 将始终为正数或零,我们可以通过将 y^2 设置为其最小值(即 0)来确定我们需要检查的最高 x 值。因此,我们需要检查所有满足的整数 x 值
x^2 <= 2n^2
这减少到
abs(x) <= sqrt(2)*n.
将此与仅检查上象限的优化相结合,您将获得优化的 psearch
def psearch(n):
count = 0
top = math.ceil(math.sqrt(2*n*n))
for x in range(1, top):
y2 = 2*n*n - x*x
#check for perfect square
y = math.sqrt(y2)
if int(y + 0.5) ** 2 == y2:
count+=4
return count
TA贡献1890条经验 获得超9个赞
y>0在第一个八分圆内搜索就足够了x<y(四个解(±n, ±n)是显而易见的,并且通过对称性,一个解会(x, y)产生 8 个副本(±x, ±y), (±y, ±x))。
通过单调性,对于一个给定y的,至多有一个x。您可以通过逐步跟随圆弧,减少y然后调整来找到它x。如果您x²+y²≤2n²尽可能严格地保持条件,您会得到下面的代码,该代码已优化为仅使用初等整数算术(为了提高效率,2x使用 代替x)。
x, y, d= 2 * n, 2 * n, 0
while y > 0:
y, d= y - 2, d - y + 1
if d < 0:
x, d= x + 2, d + x + 1
if d == 0:
print(x >> 1, '² + ', y >> 1, '² = 2.', n, '²', sep='')
以下是nbetween1和的所有解决方案100:
7² + 1² = 2.5²
14² + 2² = 2.10²
17² + 7² = 2.13²
21² + 3² = 2.15²
23² + 7² = 2.17²
28² + 4² = 2.20²
31² + 17² = 2.25²
35² + 5² = 2.25²
34² + 14² = 2.26²
41² + 1² = 2.29²
42² + 6² = 2.30²
46² + 14² = 2.34²
49² + 7² = 2.35²
47² + 23² = 2.37²
51² + 21² = 2.39²
56² + 8² = 2.40²
49² + 31² = 2.41²
63² + 9² = 2.45²
62² + 34² = 2.50²
70² + 10² = 2.50²
69² + 21² = 2.51²
68² + 28² = 2.52²
73² + 17² = 2.53²
77² + 11² = 2.55²
82² + 2² = 2.58²
84² + 12² = 2.60²
71² + 49² = 2.61²
79² + 47² = 2.65²
85² + 35² = 2.65²
89² + 23² = 2.65²
91² + 13² = 2.65²
92² + 28² = 2.68²
98² + 14² = 2.70²
103² + 7² = 2.73²
94² + 46² = 2.74²
93² + 51² = 2.75²
105² + 15² = 2.75²
102² + 42² = 2.78²
112² + 16² = 2.80²
98² + 62² = 2.82²
97² + 71² = 2.85²
113² + 41² = 2.85²
115² + 35² = 2.85²
119² + 17² = 2.85²
123² + 3² = 2.87²
119² + 41² = 2.89²
126² + 18² = 2.90²
119² + 49² = 2.91²
133² + 19² = 2.95²
137² + 7² = 2.97²
124² + 68² = 2.100²
140² + 20² = 2.100²
TA贡献1995条经验 获得超2个赞
您可以通过仅考虑一个象限并乘以 4 来优化此算法。
import math
def psearch(n, count):
for x in range( 0 , 2*n + 1):
ysquare = 2*(n**2) - x * x
if (ysquare <0):
break
y = int(math.sqrt(ysquare))
if ysquare == y * y :
print(x,y)
count+=1
return count
print(psearch(13241324,0) * 4)
输出
(1269716, 18682964)
(1643084, 18653836)
(11027596, 15134644)
(12973876, 13503476)
(13241324, 13241324)
(13503476, 12973876)
(15134644, 11027596)
(18653836, 1643084)
(18682964, 1269716)
36
添加回答
举报