ls=input().split()
circle=[i for i in range(1,int(ls[0])+1)]
jump=[]
index=0
time=1
while len(circle)>int(ls[2]):
#print(len(circle))
if(time==0): #等于0相当于是等于N
jump.append(str(circle[index]))
circle.remove(circle[index])
time+=1 #从1开始点的
time=(time+1)%int(ls[1])
index=(index+1)%len(circle)
print(' '.join(jump))
- 列表ls: 存储输入的[N, M, K]
- 列表circle:通过列表生成式得到,标识的是这N个人的标号
- 列表jump:每一轮出圈者的标号
- time:代表点数的值,通过%M使得其值在[0, N)的范围变化,此时当time的值为0时,即点数点到了M值,time值初始化为1。
- index:代表指向当前圈circle某一个值的下标,用于当点到值N时,剔除该index下标的元素
算法思想:
- 当前circle列表的长度大于题目所要求的长度时,持续循环
- 进入循环体中:
- 当time等于0时,即点数点到了M值,需要剔除当前下标为index的元素值,所以将该元素值拼接到jump列表中,并从circle列表中剔除它。此时需要将time值为1,表明重新开始点数,点数是从1开始的。
- 对time+1模M,进入下一个time值
- 对index+1模当前列表circle长度,指向下一个元素值(因为index是数组circle的下标,其值只能是在0-len(circle)变化)
- 持续while循环,直至满足条件退出
- 按题目所要求的格式输出
如果输入的K可能为0呢(这样就不属于约瑟夫环问题了),即要求将圈中全部的人都剔除,求他们的出圈顺序。只需要对上述代码的index+1语段进行修改即可。
思想:当circle的长度为1且K值为0时,说明剩下最后一个人了,直接将其出圈,并结束循环
ls=input().split()
circle=[i for i in range(1,int(ls[0])+1)]
jump=[]
index=0
time=1
while len(circle)>int(ls[2]):
if(time==0): #等于0相当于是等于N
jump.append(str(circle[index]))
circle.remove(circle[index])
time+=1 #从1开始点的
time=(time+1)%int(ls[1])
if(len(circle)==1 and int(ls[2])==0):
print(circle[0])
break
else:
index=(index+1)%len(circle)
print(' '.join(jump))