给出一些小数字和大数字,得到所需的数字 - 没有循环

时间:2010-11-25 09:18:16

标签: python

我在Python中解决codingbat上的编码问题。 make_bricks问题定义为:

  
    

我们想制作一排长达一英寸的砖块。我们有一个号码     小砖块(每块1英寸)和大块     砖(每个5英寸)。如果返回True     有可能实现目标     从给定的砖块中选择。这个     比它看起来有点难     没有任何循环可以完成。

  
make_bricks(3, 1, 8) → True
make_bricks(3, 1, 9) → False
make_bricks(3, 2, 10) → True

我想出的第一个解决方案是:

from itertools import permutations

def make_bricks(small, big, goal):
    l = small*[1]+big*[5]
    return any([(goal in i) for i in ([[sum(j) for j in set(permutations(l,i))] \
    for i in range(2,len(l)+1)])])

哪个是正确的,但被判断软件拒绝了,因为不允许进口。 所以我的下一个解决方案是:

def make_bricks(small, big, goal):
    bricks = small*[1]+big*[5]
    for step in range(len(bricks)+1,1,-1):
        for start in range(len(bricks)):
            if len(bricks[start:start+step])==step:
                if sum(bricks[start:start+step])==goal:
                    return True
    return False

这也是正确的,但在make_bricks(1000000, 1000, 1000100)之类的输入上因超时而窒息。

那么,如果不使用导入,不使用循环并且在时间限制内,你将如何在Python中解决这个问题呢?

9 个答案:

答案 0 :(得分:10)

def make_bricks(small, big, goal):
  if goal > small + big * 5:
    return False
  else:
    return goal % 5 <= small

答案 1 :(得分:5)

这是一个数学问题。假设你有S个小砖和B个大砖,你想要一个L个长度的块。

您可以使用K = min(B, L div 5)大砖块和L - 5K小砖块,这样您只需要检查是否有足够的小砖块。

div是整数除法(floor)。

编辑L-K更改为L-5K。错字。

答案 2 :(得分:4)

请注意,您只需要达到最终尺寸。因此,根据您放置砖块的顺序完全无关紧要。

然后,下一个重要的想法是尽可能使用5英寸的砖块。如果你使用其中一个,你可以覆盖5英寸,如果你使用5英寸的1英寸砖。因此,最好只使用一块砖。

现在你已经完成了:用你给定的5英寸砖块检查你可以创建的最大长度,直到你用完5英寸的砖块或你的目标长度缺少少于5英寸。无论哪种方式,都会缺少一些距离,你将不得不用剩余的1英寸砖填满。

我不会在这里给出任何代码,因为它真的是一个非常简单的问题,根据你上面所写的内容,一旦你理解了它,就应该能够轻松地解决它。

答案 3 :(得分:1)

当您拥有单个单位物品而只有一个较大尺寸的物品时,并不是那么困难,因为您可以随时使用较大的物品尽可能多地填充。

如果你有四分之一和一角硬币并且试图与它们完全一致,那就更难了,例如,如果你必须使55c失败,如果你开始2个季度就会失败,即使它低于目标。

当然,你可能会有其他组合使问题变得更加复杂,而不是“不要接近金额 - 你拥有的最小单位”。

如果你求解全等式(Ax + By)%AB = C并且总是可以使用A(x + B)+ B(yA)获得更多的方程式,它们也将等于C,这样你就可以绕过有限的你有砖/硬币或其他什么的数量。

全等式的一个例子就像(7x + 9y)%63 = 47,你可以编写一个函数来解决这些问题。我们分解为最低项,因此假设A和B是共同素数或由HCF减少它。

有一个独特的解决方案,x = 0.在这种情况下,我们实际上最终得到x = 8,y = 6,每个最大值56 + 54 = 110,这与47 mod 63一致,所以如果目标实际上是47,它不能用任何数量的7和9解决。

如果目标是110,那么如果我们有8块7和6块9,则可以解决。否则没有解决方案。

如果目标更高,将有多个无限砖块的解决方案,但我们将要求的9块砖的数量将始终为8 mod 9,因此将为8,17,26等。我们采用的最高数量为适合这个类别,并尝试用7块砖填补其余部分。如果我们拥有它们,我们可以制定目标。如果我们有33块9块砖,我们必须使用其中的26块。

一旦你解决了一致性,这就是你的算法。

答案 4 :(得分:1)

你可以用1s或5s填充5号洞,但你只能用1s填充不到5洞。例如:要制作19,你必须至少有4个1 - 如果你有100个5则没关系,如果你只有3个1你就没有运气。

所以诀窍就是看看你是否有足够的1来填补剩下的5分,然后留下足够的5分和1分来弥补其余部分。

def make_bricks(small, big, goal):
  # minimum number of 1s needed
  rem = goal % 5   # ex: 19 % 5 == 4

  if rem > small:
    # too few 1s
    return false
  else:
    # we have enough 1s; deduct what we just used
    small -= rem
    goal -= rem

    # now see if what's left will fill the rest of the hole
    return small + 5*big >= goal

希望对你有意义!

答案 5 :(得分:1)

def make_bricks(s,b,g):
  return not(g>b*5+s or g%5>s)

s =小| b =大| g =目标

答案 6 :(得分:0)

N = INT(目标/ 5)

如果目标&gt;小+大* 5:   返回False  elif(目标&lt; =小+大* 5):   如果目标&gt; n * 5 +小:
   返回False
  其他:    返回True

答案 7 :(得分:0)

这是我提出的解决方案 - 不是因为这可以得到浓缩,而是足够容易理解逻辑:

def make_bricks(small, big, goal):
  if int(goal/5) < big:
    big -= big - int(goal/5)
  return big*5 + small >= goal

答案 8 :(得分:0)

def make_bricks(small, big, goal):
    qu = goal/5
    rem = goal%5
    if big*5 <= goal and big*5 +small>= goal:
        return True
    else:
        return qu <= big and rem <= small

“我认为我们看起来像目标英寸的商数和提醒”