我们可以使用一定数量的火柴棒制作的最大N位数

时间:2016-09-28 18:43:54

标签: algorithm greedy

enter image description here

图片显示了绘制每个数字所需的棒数。 给出一个由N位数组成的数字。我想移动一些棍子以最大化数量。我不允许更改位数。它必须总是有N个数字。我也不能删除任何火柴。

示例:

given 512
answer:977
given 079
answer:997

我的解决方案是计算我们可以使用的火柴棍的数量。然后我们开始放置9直到我们用完它。然后,当我们遇到像一根火柴棒一样的问题时,我们会回溯并为数字做出不同的选择。我不确定这是否能抓住所有案例。 我的逻辑是否有任何缺陷。如果有,那么更好的方法是什么?

1 个答案:

答案 0 :(得分:0)

首先,您可以看到初始数字的实际值对我们无关紧要,因为我们可以自由移动指针。我们只需要在初始数字(s)和数字位数(n)中保留数量。所以首先我们计算初始数量中的枝条数量。

因为位数应该保持不变,我们可以将需要最少量的数字的数字分配给每个所需的数字。数字 1 只需要两根木棍,因此我们使用n 1 来初始化数字。这样我们就可以确信我们已经满足了数字要求的数量。

使用 1 初始化数字后,我们应从2*n删除s个。

s -= 2*n

因为每个 1 需要两根棍子,我们使用 n

现在为了最大限度地增加数量,我们必须尝试尽可能多地使用 9 。每个 9 需要6支,我们已经为每个数字使用了2支,所以要制作 9 数字,我们还需要4支。

我们应该注意两个例外:

  1. 我们不应该有任何额外的支持。因此,在每个步骤中,我们应该计算我们是否使用所有其他数字和最多数量的数字,是否保留任何支撑? 8 占用最多数字,需要7支。所以为了制作一个 8 数字,我们需要5个额外的棒。如果在任何步骤中剩余的棒s等于剩余的数字乘以5,我们应该使用 8 来表示其余数字。

  2. 如果剩下的棍子数量少于4个( 1 9 所需的棍棒数量),我们应该做出最好的决定剩下的数字和剩余的数据。

  3. 下面是一个python实现:

    def solve ( s, # number of sticks
                n ): #number of digits
        s -= 2*n # use n 1 digits
    
        result = ["1"]*n
    
        for i in range(n):
            if s == 0: # no sticks remained
                break
            if s == 5*(n-i): # we should use 8 from now on or else there will be extra sticks
                result[i] = "8"
                s -= 5
            elif s < 4: # not enough sticks to make a 9
                if i == n-1: # this is the last digit make the most of if
                    if s == 3: # maximum digit is 5 with 5 sticks 
                        result[i] = "5"
                        s -= 3
                    elif s == 2: # maximum digit is 4 with 4 sticks 
                        result[i] = "4"
                        s -= 2
                    elif s == 1: # maximum digit is 7 with 3 sticks 
                        result[i] = "7"
                        s -= 1
                else:
                    result[i] = "7"
                    s -= 1 # maximum digit is 7 with less than 6 sticks
            else:
                result[i] = "9"
                s -= 4
        print "".join(result)
    
    
    needed_stick = {"0":6, "1":2, "2":5, "3":5, "4":4, "5":5, "6":6, "7":3, "8":7, "9":6}
    initial_number = raw_input("Initial number: ")
    s = sum( needed_stick[c] for c in initial_number )
    n = len( initial_number )
    solve(s,n)
    

    输出:

    Initial number: 512
    977
    
    Initial number: 079
    997
    
    Initial number: 88888888888888
    88888888888888
    
    Initial number: 8881
    9995