【发布时间】:2013-05-04 20:54:25
【问题描述】:
今天,我参加了 google code jam 第 1B 轮。在代码堵塞中,有一个名为“Osmos”的问题:https://code.google.com/codejam/contest/2434486/dashboard
问题描述
问题在于有一个游戏,其中玩家是一个东西,只能吃比它小的东西,并且会随着他吃的东西的大小而变大。例如,如果玩家的尺码为 10,吃了 8 码的东西,它就会变成 18 码。
现在,考虑到玩家开始时的大小以及游戏中所有其他事物的大小,您应该给出使游戏可击败所需的最少操作数,这意味着您最终能够什么都吃。
一个操作可以是添加一些东西,也可以是删除一些东西。
我使用的代码
write_case 是一个函数,它以正确的格式为每个测试用例编写输出。我在其他的code jam回合中使用过,我知道它是正确的,inp是输入文件的文件对象。
cases = int(inp.readline())
for case in xrange(cases):
# armin is the variable containing the size of the player,
armin, n = int(inp.readline.split()[0])
# others is a list of sizes of other things
others = [int(x) for x in inp.readline().split()]
# changes obviously holds the number of required changes
changes = 0
for other in sorted(others): #we loop over all the other things in order.
if other < armin: #if the other thing is smaller, eat it, no change needed.
armin += other
else: # we'll need to make some changes
# adding is the biggest size thing the player can eat,
adding = armin - 1
if other < armin + adding: #if adding such a thing is good enough
# to eat the other thing
armin += adding + other # add it and eat them
changes += 1 #we've made a change.
else: # we can't add a big enough thing
# we have to elete it from the game (skip it from the loop)
# which is a change
changes += 1
write_case(case + 1, changes ) #output the changes.
我背后的逻辑
通过循环播放从小到大的其他东西,玩家首先会吃掉它通常可以吃的所有东西。当我们遇到不能吃的东西时,我们已经吃掉了比它小的东西,所以我们必须添加一个新的东西,这样我们才能成长。如果我们要添加新的东西,我们不妨让它尽可能大,因为我们添加的东西的大小不会改变操作的数量。我可以添加的最大可食用的东西是播放器的尺寸 -1。如果这足以吃下一个东西,我们添加它,吃我们添加的东西,而不是吃我们以前不能吃的东西。
如果添加还不够,我们不添加它,而只是删除(忽略)当前的东西)。在这一点上,我可以从循环中跳出跳过所有其他的东西(因为它们都太大而不能吃,所以列表是排序的。),但是将它们的数量添加到操作数中以加快我的解决方案,但这不会改变结果。
此代码正确计算示例输入的值,但对于比赛输入不正确。知道为什么吗?
【问题讨论】:
-
也许添加两个或更多的东西(大小为
size-1,然后是size+size-2,等等)可能会让你吃更多的东西而不是删除一个对象,如果它不能在一个之后被吃掉添加。例如,如果有很多东西(3 个或更多)可以在两次添加后吃掉,那么添加两次而不是删除所有这些东西是值得的。 -
这可能是解决方案,我必须看看你必须添加多少才能获得任何东西。我可能会蛮力解决这部分问题。