【问题标题】:When does `n` match last digits of `n^2`?`n` 何时匹配`n^2` 的最后一位?
【发布时间】:2016-01-08 13:36:43
【问题描述】:

我正在解决一个编程问题。

1n 中查找所有具有数字属性的数字xx 匹配x^2 末尾的数字。

例如:

5 matches last digit of 5^2 (25)
6 matches last digit of 6^2 (36)
25 matches last digits of 25^2 (625)
76 matches last digits of 76^2 (5776)
376 matches last digits of 376^2 (141376)
625 matches last digits of 625^2 (390625)
etc.

有谁知道一个数字在平方的最后一位数字中匹配自身的数字标准是什么?

我正在用 Python 编程,我只能使用数字运算,例如 /%//*+ 等。

我不能使用strlen 或字符串函数来分割数字。

【问题讨论】:

标签: python algorithm numeric


【解决方案1】:

返回这些数字的列表的函数。

def mathcing_squared(n):
    return [x for x in range(1, n + 1) if str(x ** 2).endswith(str(x))]

所以如果n650,它会返回

[1, 5, 6, 25, 76, 376, 625]

【讨论】:

    【解决方案2】:

    好的,这是修改后的版本:

    LastNum=int(input("Enter end limit: "))
    def y(num):
        count=0
        while num!=0:
            num=num//10
            count=count+1
        return count
    def LastDigitMatch(x):
        if x%(10**y(x))==(x**2)%(10**y(x)):
            return True
        else:
            return False
    print('The required list of numbers: ')
    for num in range(1,LastNum+1):
        if LastDigitMatch(num):
            print(num,end=', ')
    

    我发现Giorgi Nakeuri 的版本(参见对 Dave Galvin 帖子的评论)是所有版本中最快和最简单的。我编辑了代码:

    import math
    LastNum=int(input("Enter the end limit: "))
    print('The required list of numbers:')    
    for x in range(1,LastNum+1):
        if x%(10**math.floor(math.log10(x)+1))==(x**2)%(10**math.floor(math.log10(x)+1)):
            print(x,end=', ')
    

    【讨论】:

    • 不适用于数字 >= 10... 仅适用于 1、2、3、4、5、6、7、8、9。问题:您必须检查所有最后一位数字。例如:您的程序匹配“16”,但 16^2 是 256,而 16 不在 256 的末尾。需要检查所有数字结尾。!!!!!!!!!
    • 哦,对了!我误解了你的问题。我虽然 x 的最后一个 didt 匹配 x^2 的最后一个数字。我的错。编辑它。
    • 谢谢!我想看看你的回答,非常感谢!
    • 已添加!!再次对于 python 2.x,请将最后一行更改为:print num,
    • 这很好用,但是对于较大的 n 值会很慢。
    【解决方案3】:

    假设 x 有 k 个数字。那么 x^2 以 x 的数字结尾当且仅当 x^2 - x 以 k 个零结尾,即如果 x(x-1) 以 k 个零结尾。

    计算 2 进入 x 和 x-1(总和)的次数,然后对 5 进行相同的计算。如果其中的最小值至少与位数一样大,则您获胜。如果没有,你不会。

    例如,考虑 5。5 进入 5 一次,进入 4 次零次,2 进入 5 次零次,进入 4 两次。 1 和 2 的最小值为 1。 5 有一个数字,所以你有一个赢家。


    查找 1 和 n 之间的所有此类数字的简单方法是检查 5 的幂的倍数。由于对于每个 k 位数字,您需要 5^k 作为一个因数,请检查 5^k 和所有的倍数不要超过k位数。这可能是 x 或 x-1,因此您还需要检查上面的数字。

    所以要检查的数字是:

    k=1: 5, 6
    k=2: 25, 26, 50, 51, 75, 76
    k=3: 125, 126, 250, 251, 375, 376, 500, 501, 625, 626, 750, 751, ...
    k=4: 625, 626, 1250, 1251, ...
    

    等等……

    而您需要检查的所有这些都是最小设置位是否让您至少获得 k 2s。

    请注意,对于 k=3 和 k=4,625 都会出现,但这很好,因为 0625 是有效的。在实践中,您只需要检查一次,因此您可以将自己限制为本身至少为 k 位的倍数。

    【讨论】:

    • 或者对于 376:我们有 2 进入 376 3 次和 375 零次。我们有 5 次进入 376 次,进入 375 次 3 次。 Min(3,3)=3,而 376 是 3 位数,所以你又多了一个赢家。显然你只需要检查偶数2s,就可以快速找到第一个设置位。检查5s是日志时间。
    • 这只是检查一个数字。要找到 1 和 n 之间的所有好数字,这将是 nlog(n),所以可能太慢了。请注意,如果 x 可以被 2 和 5 整除,则 x-1 不能被任何一个整除。但是如果最小值是 k,x >= 10^k,并且至少有 k+1 位,那么就不会是赢家。因此,您只需要查看一个数字 x,其中 x 可以被 2 或 5 整除,并且 x-1 可以被另一个整除。因此对于任意数量的数字 k,您需要查看 5^k 和 (5^k)+1。对于其中的每一个,检查 2 的数量。如果它是好的,取那个数字和任何不增加数字的倍数。
    • 简单算法是o(n)。只需迭代并检查(x^2 - x)%(10*(floor(log10(x)) + 1)) == 0
    • @GiorgiNakeuri 而不是 log(n)。
    • 你说你的算法是nlog(n)。我已经向你展示了 n 个算法。或者我只是误解了一些东西。你能更详细地解释一下为什么你的查找1到n之间所有这些数字的算法是log(n)吗?
    【解决方案4】:

    您好,我写了这个答案:

    n=int(input('n='))
    
    for m in range(1, n+1):
        d=m**2
        x = m
    
        all = 0
        all2 = 0
    
        while x != 0:
            if x%10 == d%10:
                all += 1
            x = x//10
            d = d//10
            all2 += 1
    
        if all == all2:
            print m
    

    请让我知道你的想法——它有效!

    【讨论】:

      【解决方案5】:

      不是一个完整的标准,但可以作为起点:

      第一:记住,乘法的最后一位是第一个操作数的最后一位乘以第二个操作数的最后一位的乘法的最后一位。

      由于乘以一个数,因此可能的组合有:0x0、1x1、2x2、3x3、4x4、5x5、6x6、7x7、8x8 和 9x9。

      与操作数最后一位相同的乘法是0x0、1x1、5x5和6x6。

      因此,您可以从仅测试以 0、1、5 或 6 结尾的数字开始。

      对于这些数字中的每一个,您可以通过在它们前面加上数字 1、2、3、...、9 来构建一个两位数。因此,对于数字 0,您有 10,20,30,...,90 。你现在必须找出这些数字中的哪一个,乘以它的ef,产生一个结果,它的倒数第二个数字与它相同。让这个两位数为10a+b,其中a 是十位,b 是个位。 b 的值已经固定,是 0、1、5 或 6 之一。为 b 设置一个值,并让 (10a+b)(10a+b) 为 100a^2 + 20ab + b^2 相乘的结果10a+b 由它自己决定。

      我们对这个数字的十位感兴趣,所以我们把它分成10,得到10a^2 + 2ab + b^2/10,并做一个10的模来隔离十位。在表达式中替换b 的值,对最后一项执行整数除法。例如,对于b=5,表达式为(10a^2 + 20*5*a + 2) mod 10。使这个表达式等于a,你就得到了一个方程,它给出了a 的哪些值与等式匹配。

      【讨论】:

      • 感谢您的评论。我试图理解它并实施它。 :) 您能否也请检查我发布的解决方案作为我自己问题的答案?
      • 我对 Python 一无所知,但这似乎是一个简单的解决方案。如果您已经对其进行了测试并且可以正常工作,那么它可以正常工作:) 我已经使用 Coding Ground 进行了快速测试,并使用 n=1000000 进行了测试并且可以正常工作。
      • 对于 k 位,您只需要检查 5^k 的倍数和这样的倍数加 1。请参阅我的答案。
      猜你喜欢
      • 2022-01-11
      • 2018-06-23
      • 1970-01-01
      • 2017-05-15
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 2017-08-23
      相关资源
      最近更新 更多