【问题标题】:Palindrome from the product of two 3-digit numbers来自两个 3 位数字的乘积的回文
【发布时间】:2011-09-18 09:13:29
【问题描述】:

我想通过两个 3 位数字相乘得到最大的回文数。

我从 a 和 b 都为 999 开始,并随着每次乘法的发生而递减 a 和 b。

a = 999 #Defining Variables
b = 999

for i in range (1000): 
    c= a*b                          #multiply a to b
    if int(str(c)[::-1]) == c:
        print c
    a = a-1                         #decrement the value of a
    c=a*b                           #multiply a by the decremented a
    if int(str(c)[::-1]) == c:
        print c

    b = b-1                         #decrement b so that both a and b have been decremented

结果出现了 698896、289982、94249、69696...,其中 698896 是第一个数字。目前我仍在试图找出我缺少什么。

【问题讨论】:

  • 不检查是一位数还是两位数。除非您将 010...090 视为三位数(但在这种情况下需要额外的代码:])
  • 多么糟糕的cmets! “c= a*b #multiply a to b”?什么样的程序员需要向他们解释这一行?
  • 感谢您专注于我的 cmets 而不是糟糕的代码:P 我认为这至少有助于理解我创造的可憎之物。
  • 仅供参考,这是项目欧拉问题 #4...
  • @Rosh Oxymoron 感谢您让我查找 INTERCAL:D

标签: python palindrome


【解决方案1】:

您不能以交替方式递减 ab,因为这样会丢失像 a = 999 和 b = 997 这样的值对。

改用嵌套循环,从 999 开始倒数。

类似

def is_pal(c):
    return int(str(c)[::-1]) == c

maxpal = 0
for a in range(999, 99, -1):
    for b in range(a, 99, -1):
        prod = a * b
        if is_pal(prod) and prod > maxpal:
            maxpal = prod

print maxpal

编辑:在 Paul 评论之后修改了下限。

【讨论】:

  • range(999,100,-1) 不包括 100。试试range(999,99,-1)
  • 保罗,不过,100*999 小于 698896。此外,对于所有自然 x,x*100 以 00 结尾,这意味着 x*100 的集合中没有回文。
  • 还请注意,我们可以通过仅检查 a >= b 的数字来轻松地将问题空间减半。否则,我们同时计算 ab 和 ba,这显然不是特别有用。只要 a*b
  • @Voo:我只检查a >= b的数字
  • @Emil:没错,100 不可​​能是回文的一个因素,但是这些代码 sn-ps 以各种神秘的方式被复制/粘贴。最好显示正确的范围表达式以获得所有 3 位数字,而不是保持原样(因为“100 无论如何都无关紧要”),并留下一个错误的范围表达式,无法提醒新手经常 -错误的范围终止符。
【解决方案2】:

你的算法是错误的。您将需要测试 a 的所有值到 b 的所有值,这可以通过使用两个循环(外部用于 a,内部用于 b)来解决。我还建议你使用 a 和 b 作为循环索引,这样可以简化逻辑(更容易记住)。

考虑将回文检查也移到它自己的函数中,以使代码更易于理解。


我不是 Python 程序员,但这是我的 PHP 解决方案:

function palindrome($x) {
  $x = (string) $x;  //Cast $x to string
  $len = strlen($x); //Length of $x

  //Different splitting depending on even or odd length
  if($len % 2 == 0) {
    list($pre, $suf) = str_split($x, $len/2);
  }else{
    $pre = substr($x, 0, $len/2);
    $suf = substr($x, $len/2+1);
  }

  return $pre == strrev($suf);
}

$max = array(0, 0, 0);

//Loop $a from 999 to 100, inclusive.
//Do the same over $b for EVERY $a
for($a = 999; $a >= 100; $a--) {
  for($b = 999; $b >= 100; $b--) {
    $x = $a*$b;

    if(palindrome($x)) {
      echo $a, '*', $b, ' = ', $x, "\n";
      if($x > $max[2]) {
        $max = array($a, $b, $x);
      }
    }
  }
}
echo "\nLargest result: ", $max[0], '*', $max[1], ' = ', $max[2];

【讨论】:

    【解决方案3】:

    最快的方法是从最大值 999x999=998001 之前的最大 polindrome 向下循环。 997799,996699,.. 并检查是否可以在 100..999 范围内分为 A 和 B。我的代码花了 2200 个周期。您的代码大约需要 4K 到 8K 周期。

    Sub method3a()
    iterations = 0
    For a = 997 To 0 Step -1
        R = a * 1000 + Val(StrReverse(a))
        b = 999      ' R=b*s
        s = Int(R / b)
        While b >= s
            iterations = iterations + 1
            If R = b * s Then
                Debug.Print "Result=" & R & " iterations=" & iterations
                Exit Sub
            End If
            b = b - 1
            s = Int(R / b)
        Wend
    Next
    

    结束子

    【讨论】:

      【解决方案4】:
      i = 1000000
      test = 0
      while test == 0:
          i += -1
          str_i = str(i)
          if str_i[0:3] == str_i[3:][::-1]:
              for j in range(100, 1000):
                  if i % j == 0:
                      if i/j < 1000 and i/j > 100:
                          print('Largest Palindrome: %s = %s * %s' % (i, j, i//j))
                          test = 1
                          break
      

      【讨论】:

        【解决方案5】:

        在 C# 中 - gist 中的解决方案 - https://gist.github.com/4496303

        公共课工 { 公共工作者(){

            }
            public void start()
            {
                int MAX_NUMBER = 999;
                for (int Number = MAX_NUMBER; Number >= 0; Number--)
                {
                    string SNumberLeft = Number.ToString();
                    string SNumberRight = Reverse(Number.ToString());
                    int palindromic = Convert.ToInt32(SNumberLeft + SNumberRight);
        
                    for (int i = MAX_NUMBER; i >= 1; i--)
                    {
                        for (int l = MAX_NUMBER; l >= 1; l--)
                        {
                            if ((i * l) - palindromic == 0)
                            {
                                System.Diagnostics.Debug.WriteLine("Result :" + palindromic);
                                return;
                            }
                        }
                    }
        
                   // System.Diagnostics.Debug.WriteLine( palindromic); 
                }           
        
            }
        
            public string Reverse(String s)
            {
                char[] arr = s.ToCharArray();
                Array.Reverse(arr);
                return new string(arr);
            }
        
        
        
        }
        

        【讨论】:

          【解决方案6】:

          我做到了,并且优化并减少了搜索的步骤数

          时间 0.03525909700010743

          回文 = 906609

          计数 = 3748

          我 = 913

          j = 993

          from timeit import timeit
          
          def palindrome(number):
              return str(number) == str(number)[::-1] # chek number is polindrome
          
          def largest():
              max_num = 0
              count = 0
              ccount = 0
              ii = 0
              jj = 0
              for i in range(999, 99, -1): # from largest to smallest
                  for j in range(999,  i - 1, -1): # exclude implementation j * i
                      mult = i * j # multiplication
                      count += 1
                      if mult > max_num and palindrome(mult): # chek conditions
                          max_num = mult #remember largest
                          ii = i
                          jj = j
                          ccount = count
              return "\npalindrome = {0}\ncount = {1}\ni = {2}\nj = {3}".format(max_num, ccount, ii, jj)
          print ("time", timeit('largest()', 'from __main__ import largest', number = 1))
          print(largest())
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多