【问题标题】:Given n, find how many n-digit numbers are there such that the number has prime digit at prime indices and is divisible by m?给定n,找出有多少个n位数字使得该数字在素数索引处具有素数并且可以被m整除?
【发布时间】:2021-03-09 02:13:54
【问题描述】:

特殊数字是这样的数字在素数索引上具有素数(2、3、5、7),在非素数索引上具有非素数。 (例如,15743 - 素数索引 (2, 3, 5) 具有素数 (5, 7, 3))。 能被 m 整除的 n 位特殊数有多少个。

例如,对于 n=2 和 m=2,答案将为 [12,42,62,82,92],因此为 5。

我编写了一个回溯算法来查找特殊数字的所有此类排列,然后检查这些特殊数字中的每一个是否可以被 m 整除并返回计数。这适用于 n 和 m 的小值,但问题是 n、m 值在 0-500 的范围内。

var primes = [2, 3, 5, 7]
var nonPrimes = [1, 4, 6, 8, 9]


n = 2 // number of digits
m = 2 //divisor
k = 0 //remainder

function rec(index, temp, count) {
  if (temp.length >= n) {
    if (Number(temp) % m === k) {
      /* console.log(temp) */
      count += 1
    }

    return count
  }
  if (primes.includes(index)) {
    for (num1 in primes) {
      temp += primes[num1];
      count = rec(index + 1, temp, count)
      temp = temp.slice(0, -1)
    }
  } else if (nonPrimes.includes(index)) {
    for (num2 in nonPrimes) {
      temp += nonPrimes[num2];
      count = rec(index + 1, temp, count)
      temp = temp.slice(0, -1)
    }
  }
  return count
}

console.log("number of n-digit special numbers which are divisible by m with remainder k is ", rec(1, "", 0))

【问题讨论】:

  • 为什么这个标签是python?
  • @DaniMesejo 搞错了,我在找算法,语言无所谓。
  • 索引是从 1 开始的?为什么 25743 就是一个例子,而 2 是素数并且位于非素数索引上?
  • @trincot 已更正。是的,索引是基于 1 的..

标签: javascript algorithm math permutation primes


【解决方案1】:

由于逐位递归可以使它们相互依赖,因此对小于 m 的所有余数求解并返回余数 0 的解。给定一个“特殊”数字的计数表,剩余数为 r除以m 时,制表至ith 索引。然后将索引行列表i + 1

(1) Transform the current row of remainders,
each storing a count, multiplying by 10:

  for remainder r in row:
    new_r = (10 mod m * r) mod m
    new_row[new_r] += row[r]
  
  row = new_row
    
(2) Create new counts by using the new
possible digits:

  initialise new_row with zeros

  for d in allowed digits for this ith row:
    for r in row:
      new_r = (r + d) mod m
      new_row[new_r] += row[r]

例如n = 2, m = 2:

row = [None, None]
# We are aware of the allowed digits
# at the ith row
row[0] = 3  # digits 4, 6 and 8
row[1] = 2  # digits 1, 9
row = [3, 2]

(1)变换:

  new_row = [0, 0]

  remainder 0:
    new_r = (10 mod 2 * 0) mod 2 = 0
    new_row[0] += row[0] = 3
    
  remainder 1:
    new_r = (10 mod 2 * 1) mod 2 = 0
    new_row[0] += row[1] = 5
  
  row = new_row = [5, 0]

(2) 创建新计数:

  new_row = [0, 0]
  
  d = 2:
    rd = 2 mod 2 = 0
    
    r = 0:
      new_r = (0 + 0) mod 2 = 0
      new_row[0] += row[0] = 5
    r = 1:
      new_r = (1 + 0) mod 2 = 1
      new_row[1] += row[1] = 0
      
  d = 3:  # Similarly for 5, 7
    rd = 3 mod 2 = 1
    
    r = 0:
      new_r = (0 + 1) mod 2 = 1
      new_row[1] += row[0] = 5
    r = 1:
      new_r = (1 + 1) mod 2 = 0
      new_row[0] += row[1] = 5  # unchanged
      
  row = new_row = [5, 15]
  
[12,42,62,82,92]

[13,15,17,
 43,45,47,
 63,65,67,
 83,85,87,
 93,95,97]

【讨论】:

  • 我经历了两次,仍然不明白。此外,这是否适用于更高的 n 值,比如 400-500?
  • @drWatson 随时要求提供更具体的说明。这里的复杂度是 O(n * m) 所以它应该很容易处理 500 的 n 和 m。
  • 你可以用 python/JS 编写代码吗?如果我希望余数不为零,这种方法会起作用吗?
  • @drWatson 太棒了!这是您提到的示例的代码,n=2,m=4:ideone.com/V19tJA(请注意,不需要k,因为该行将包含所有余数的列表。)
  • @drWatson 这是个好问题。通过阅读我感兴趣的问题并尝试解决更多问题以及学习其他人的解决方案,我学到了很多东西。这种特殊的方法属于“动态规划”。
猜你喜欢
  • 2020-12-06
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多