如果在Python中输入大数字时如何有效地找到范围内的完美正方形

时间:2014-11-13 04:12:07

标签: python largenumber perfect-square

问题是当输入数字非常大时,如何有效地找到给定范围内的完美正方形。我的解决方案是出现Time Limit Exceeded错误。我已经检查了以下链接,但他们没有解决我的问题:
- Python Program on Perfect Squares
- How could I check if a number is a perfect square?
- Fastest way to determine if an integer's square root is an integer(我不知道如何在Python中实现此链接中给出的解决方案。)

问题是:

  

输入格式:第一行包含T,即测试用例的数量。随后是T测试用例,每个测试用例都在换行符中。每个测试用例包含两个空格分隔的整数,表示A和B.找到A和B范围内的所有完美正方形(包括两者)。

输入示例:

2
3 9
17 24

我写的代码是:

import math
def is_perfect_square(n):
    return n % n**0.5 == 0

t = int(raw_input())
for i in range(t):
    numbers = map(int, raw_input().split())
    count = 0
    for j in xrange(numbers[0], numbers[1] + 1): # I also tried range() which gave memory error
        if (is_perfect_square(j)):
            count = count + 1

    print count

虽然此代码适用于较小的数字,但是对于大输入会产生Time limit exceeded错误。

(注意:gmpy不是一个选项,因为代码必须在没有gmpy模块的在线编译器上运行

3 个答案:

答案 0 :(得分:9)

不是从A循环到B并检查完美的正方形,为什么不只是循环从sqrt(A)sqrt(B)的整数并对每个方块进行平方,为您提供答案。

例如,让我们找到1000到2000之间的平方数:

sqrt(1000) = 31.6  -->  32  (need the ceiling here)
sqrt(2000) = 44.7  -->  44  (need the floor here)

因此,我们的答案是:

322 = 1024
332 = 1089
342 = 1156
352 = 1225
362 = 1296
372 = 1369
382 = 1444
392 = 1521
402 = 1600
412 = 1681
422 = 1764
432 = 1849
442 = 1936

答案 1 :(得分:0)

这就是我的尝试:

>>> def isperferct_square(n):
...     return int(math.sqrt(n))*int(math.sqrt(n)) == n
... 
>>> isperferct_square(10)
False
>>> isperferct_square(9)
True
>>> isperferct_square(10000000000000000000)
False
>>> isperferct_square(112312424354957359732985732897583297592735932)
False
>>> isperferct_square(10000000000)
True
>>> 

答案 2 :(得分:0)

您的代码中存在多个错误,例如numbers = map(int,raw_input()。split())必须在循环之外。与counter = 0相同。无论如何,这里有一个代码,适用于甚至非常高的整数:

t = map(int,raw_input().split())

def is_perfect_square(x):
    if x < 0:
        raise ValueError('square root not defined for negative numbers')
    n = int(x)
    if n == 0:
        return False
    a, b = divmod(n.bit_length(), 2)
    x = 2**(a+b)
    while True:
        y = (x + n//x)//2
        if y >= x:
            return x
        x = y

count = 0
for i in t:
    if is_perfect_square(i)**2 == i:
        count+=1

print count