当前位置: 华文星空 > 知识

我这里有一个非常有趣的问题,我已经做出来了。各位大佬能做出来且用编程语言写出来吗?

2021-05-27知识

提供一个计算机能理解的思路吧。

抓猫的时候,和这个猫之前的生活毫无关系,只和这只猫现在有可能在哪儿有关。开哪个门,决定了这只猫明天可能在哪儿。只要你可以不断压缩这个可能性,最后压缩到一个门里,这问题就解决了。

最开始的时候,这只猫的可能性是1 2 3 4 5 6 7。

如果抓1号门,确定了它不在1,那接下来一天它的可能性还是1 2 3 4 5 6 7。所以这一下是没意义的。因为猫可以从3到2。

如果抓2号门,确定了它不在2,那接下来一天它的可能性就变成了2 3 4 5 6 7。因为它不在2,所以没办法跑到1去。这就压缩了可能性。

第二天如果抓2,那结果还是2 3 4 5 6 7,毫无进展,所以没意义。

抓3,结果会变成1 3 4 5 6 7,变个形式,给接下来的一天提供方便。

第三天,抓4,可以确保接下来一天没有3,然后可能性变成2 4 5 6 7。以此类推,最后就能把门数减少到1个。核心技巧就是如果有一个门,它左边不可能右边可能,抓右边,这样这个门下次就不可能了。

当然怎么抓更快这是人类的思路,这个算法有个好处就是对于计算机来说足够暴力。你并不需要去教计算机应该抓哪个门,你让它全抓了然后剪枝加BFS即可。由于结果只和当前状态有关,所以最多出现 2^n 种可能性,可以有效地剪枝,避免无限深度。配合BFS,总可以最快速度地找到最优解。

import queue class Solution : def __init__ ( self , doors , path = [], possible = set ()): self . path = path self . possible = possible self . doors = doors def generate_next_steps ( self ): if not self . possible : return None next_steps = [] for i in self . possible : path = self . path + [ i ] possible = set () for elem in self . possible : if elem != i : if elem - 1 >= 1 : possible . add ( elem - 1 ) if elem + 1 <= self . doors : possible . add ( elem + 1 ) s = Solution ( doors = self . doors , path = path , possible = possible ) next_steps . append ( s ) return next_steps def find_cat ( n ): checked_combination = set () solutions_queue = queue . Queue () solutions_queue . put ( Solution ( doors = n , path = [], possible = set ( i for i in range ( 1 , n + 1 )))) while True : s = solutions_queue . get () next_steps = s . generate_next_steps () if next_steps is None : return s . path for n in next_steps : if tuple ( n . possible ) not in checked_combination : checked_combination . add ( tuple ( n . possible )) solutions_queue . put ( n ) print ( find_cat ( 7 ))

这里提供一个随手写的代码,核心思路就是上面说的,对于每种可能性,分别测试开其中某扇门之后的结果,然后剪去已经试过的状态,BFS。

python find_cat.py [2, 3, 4, 5, 6, 2, 3, 4, 5, 6]