题目
题目是英文题目,大意是有N个人互相传递珠子,每个人都有他自己的下标(1-N),珠子最开始在一个人手中,然后珠子进行传递,珠子传递的过程中,只能传给特定的人,比如,总共3个人,那么每个人分别为:1,2,3,珠子本来在第2个人手中,那么这个珠子下次只能传给1,因为2%1==0,而3%2!=0,所以珠子只能传给1,此时珠子在1手中,1能传给2和3,因为3%1=0,2%1=0。在传递不超过Y次的情况下,若是珠子回到最开始的人2手中了,回到2几次,那么我们就记有几种路径,并将该值返回。
有三个输入,input1是N,代表有几个人;input2是X(表示第几个人),表示珠子最开始在第几个人手中;input3是传递的次数Y,即最多传递Y次珠子。输出out是整数。
示例:
输入:
input1——3
input2——2
input3——4
输出:
out——3
解释:
球最开始在2手中,那么2可以传给1,这是传了一次,1能传给2和3…
2-1-2(传两次)
2-1-2-1-2(传四次)
2-1-3-1-2(传四次)
共有3种路径球能够重新返回到2手中。
思路
在读懂题目后,我一开始也是没什么思路,解题的逻辑没有理清楚,因为你既要考虑球能传给谁,还要考虑这个人是不是最开始的人,我们传递的次数有没有超过给的限定次数,如果没超过,同时球又回到了最开始人手中,那么成功返回的次数就要+1,然后球再怎么传。
想着想着,觉得这题必须要用递归实现。我们可以分析示例,我们看到球从2到1后,1可以传给2和3,那么我们这两个路径都要进去判别,判别后再返回,这一步骤的实现肯定需要递归才能实现。同时我们还要保存每次球在哪个人手中,球能往哪里传。
具体思路:
- 定义函数,用input4来保存每次球在哪一个人手中,input4初始定义为input2,nums定义为路径次数,作为输出;
- 用数组people来保存这N个人的数组,同时我们需要将input4从数组中移除,因为球不可能传给自身,同时我们还要定义数组adapt,adapt用来保存input4能够传给res中哪个人的下标;
- 接下来我们遍历数组r,表示我们将球传给r中的一个人了,因为我们已经传了一次,所以input3-1,此时还要判断这个人是否是最开始的人input2,来对输出进行记录;
- 判断后让这个人作为新的input4进入递归,即返回步骤1;
- 当input3==0时递归停止,返回;
- 返回路径nums。
代码
这个代码我敲出来了大部分,但是递归的返回我没有弄好,问题在这两行,这两行是别人修改的代码:
tmp=find(input1,input2,input3,0,i)#递归
nums+=tmp
我本来的代码是:
find(input1,input2,input3,nums,i)#递归
可以看到她用了一个tmp变量来在最外层保存路径次数,而我是直接在内部保存,但是我这样递归返回不了,我也没搞清楚问题的原因在哪里,所以用了她的代码。
def find(input1,input2,input3,nums,input4=input2):
#每次用input4来更新球在哪里,下一步投往哪里
if input3==0: return 0
adapt=[]
people=[n for n in range(1,input1+1)] #所有人的数组
people.remove(input4) #从数组中去除input4本身
#input4可以传递到的所有点(整除点)
for i in people:
if max(i,input4)%min(i,input4)==0:
adapt.append(i)
input3-=1
#input4传球,进入递归,更新input4为当前人
for i in adapt:
if i==input2:
nums+=1
tmp=find(input1,input2,input3,0,i)#递归
nums+=tmp
return nums
递归之路漫漫无期啊。