问题描述
班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。在一个游戏中,需要小朋友坐一个圈,每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?小朋友编号为1,2,3,…N,输入第一行,一个整数N(3<N<100000),接下来一行N个整数,由空格分开。要求输出一个整数,表示满足条件的最大圈的人数。
个人思路
代码如下
第一种:超时
# """
# 按照题目描述,很容易理解成x崇拜的人位于x的右边,也就是这组整数相邻的人构成崇拜关系,
# 然而结合图形和输入的N个整数,发现如果将这些整数看成是一个数组nums,那么构成崇拜关系的规律应该是x崇拜nums[x-1]
# """
# n = int(input())
# nums = [0] + list(map(int,input().split()))
# max_ = 0
# for i in range(1,len(nums)):
# con = 0
# lst = []
# x = nums[i]
# while x not in lst:
# lst.append(x)
# x = nums[x]
# con += 1
# if con > max_:
# max_ = con
# print(max_)
第二种:优化,根据上一个方法的思路,进行优化
import os
import sys
sys.setrecursionlimit(1000000)
#n,f赋值方便验算,提交时记得改掉
n= 9
f = [0, 3, 4, 2, 5, 3, 8, 4, 6, 9]
vis=[0]*(n+1)#存储从1开始的崇拜者顺序,从1开始,vis[i]的下标表示前一个小朋友崇拜的对象所在的位置下标
global ans
ans=0
def dfs(u,i):
if vis[u]:#vis[u]访问过
global ans
ans=max(ans,i-vis[u])#用当前列表长度i减去已经在T中的那个小朋友的下标
return
vis[u]=i#
dfs(f[u],i+1)#f[u]:寻找下一个崇拜者 i+1:当前构成环的长度+1
for i in range(1,n+1):
if not vis[i]:
dfs(i,1)#从i开始遍历,环默认为1
print(vis)
# vis的全部情况
# [0, 1, 3, 2, 4, 5, 0, 0, 0, 0]
# [0, 1, 3, 2, 4, 5, 1, 0, 2, 0]
# [0, 1, 3, 2, 4, 5, 1, 1, 2, 0]
# [0, 1, 3, 2, 4, 5, 1, 1, 2, 1]
print(ans)
关于dfs的部分解析