最大数字可以被5和6整除

时间:2016-07-30 15:57:48

标签: math numbers division

我得到一个数字数组,其中元素的范围是0-9,我需要使用数字构造最大数字,使得形成的数字可以被5和6整除。如何有效地解决这个问题更好的算法。它不需要使用提供的所有数字,但形成的数字应该是最大的,并且可以被5和6整除。

1 个答案:

答案 0 :(得分:2)

tl; dr问题基本上可以简化为查找数字的最大子集,其总和可以被3整除。这可以在数字的线性时间内完成。

可以使用prime factorizationdivisibility rules解决此问题。

6的素因数分解为2 * 3。鉴于你还需要5的可分性,这意味着你要形成一个可被2,3和5整除的数字。

我们可以重新组合三个除数:2 * 5和3.换句话说,数字必须能被10和3整除:

  • 只有以零结尾的数字才能被10整除。这意味着,从您的数字数组中,您需要留出零以满足此可分性要求。

  • 只有数字总和最多为3的数字才能被3整除。这意味着,从数组中的其余数字开始,您需要查找其总和可分的最长子集三个(通过在较小的数字上选择较大的数字来打破长度关系)。

一旦有了数字,就可以通过对从最大到最小的数字进行排序来形成数字(最后出现零)。

我们因此将问题简化为找到其总和可被3整除的子集。我们可以首先注意到所有可被3整除的数字(即零,3,6和9)可以而且应该总是被选中。

对于剩余的数字(1,2s,4s,5s,7s和8s),你要选择可被3整除的组(例如,1 + 2,2 + 5 + 8等) 。如果我们将等于1 mod 3的数字表示为①,将等于2 mod 3的数字表示为②,则形成​​这些组的唯一可能性是①+①+①,①+②和②+②+②。

以下Python解决方案将所有这些想法放在一起:

def get_n_mod_3(digits, n):
  return sorted(d for d in digits if d % 3 == n)

def solve(digits):
  # select all (0 mod 3)
  selected = get_n_mod_3(digits, 0)
  if not selected or selected[0] != 0:
    # not divisible by both 2 and 5
    return None
  # select all (1 mod 3) and (2 mod 3)
  set1 = get_n_mod_3(digits, 1)
  set2 = get_n_mod_3(digits, 2)
  while True:
    # to simplify what follows, store the longer set in set1
    # and the shorter in set2
    if len(set1) < len(set2):
      set1, set2 = set2, set1
    if len(set1) == 3 and len(set2) < 2:
      selected.extend(set1)
      break
    elif set1 and set2:
      selected.append(set1.pop())
      selected.append(set2.pop())
    elif len(set1) < 3:
      break
  return ''.join(map(str, sorted(selected, reverse=True)))

print solve([1, 4, 2, 2, 9, 0, 2, 1, 5, 5, 7, 2, 0, 8, 1, 1, 8])

(要将此转换为线性时间解决方案,我们所要做的就是用counting sort替换O(n logn)sorted()调用。)