50枚棋子围成圆圈
编上号码1、2、3、4、…50,顺时针开始取,每隔一枚棋子取出一枚,要求最后留下的枚棋子的号码是42号,那么该从几号棋子开始取呢?
问题分析
不论是取棋子模型还是踢人模型,要分析,每轮取走的最大的数字,是否是上一轮留下的最大的数字,举个例子,如果第一轮从1开始取,那么第一轮留下的最后的一个数字是50,那么第二轮就是从2开始取,第二轮50被取走,那么第三轮就要留一枚4,从第二个8开始取,以此类推。
那么一共要取几轮呢,题目中是每隔一枚棋子取走一枚,不难看出25<50<26,即第6次一定能全部取走,也就是说最多第6次取完49枚棋子,留下最后一枚棋子。
程序代码
import sys
def qizi(n): #输入n,显示n个棋子的编号
qu0 = []
for i in range(1, n + 1):
qu0.append(i)
print('一共有', n, '个棋子,序号分别为:')
for i in range(len(qu0)): #每打印10个数,换行一次
if (i+1) % 10 != 0:
print(qu0[i], end='\t')
else:
print(qu0[i], end='\n')
return qu0
def quqizi1(qizi_n): #输入列表[1,2,3,4,……,n],输出为列表[1,3,5,……]
b = len(qizi_n)
qu = []
for i in range(int(b / 2)):
qu.append(qizi_n[2*i])
if len(qizi_n) %2 == 1: #当输入列表的长是奇数时,最后一个值取不到,所以此处将最后一个值也添加到新的列表里面
qu.append(qizi_n[-1])
return qu
else:
return qu
def quqizi2(qizi_n): #输入列表[1,2,3,4,……,n],输出为列表[2,4,6,……]
b = len(qizi_n)
qu = []
for i in range(int(b / 2)):
qu.append(qizi_n[2*i+1])
return qu
while True: #检测输入的是否是正整数,如果不是,则继续输入,直到输入的是正整数为止
n = int(input('请输入棋子数:'))
if n < 1:
print('你输入的不正确,请重新输入:')
continue
else:
break
qu0 = qizi(n)
qu1 = quqizi2(qu0)
print('第',1,'次取完棋子后,剩余的棋子序号为:', qu1)
if n <= 3:
sys.exit() #≤3的情况都只是取完一次就可以剩最后一个了,所以可以直接退出
num = 1
x = qu0
y = qu1
while True:
qu_n = []
if x[-1] == y[-1]:
qu_n = quqizi2(y)
else:
qu_n = quqizi1(y)
x = y
y = qu_n
num += 1
if len(y) == 1:
print('第', num, '次取完棋子后,剩余的棋子序号为:', y)
break
print('第',num,'次取完棋子后,剩余的棋子序号为:', y)
此代码运行如下:
从执行结果来看,第一次从1开始取棋子,那么50个棋子,最后剩的棋子序号是36。由此可见,如果顺第一个先取36号棋子,那么最后剩的棋子序号则是1。题目中说的是最后一枚剩下的是42号,可以理解为先取42,求最后剩的几号棋子。如果先取的是42号,相当于先取的是36号后面的第6枚棋子,那么最后剩的也应该是1后面的第6枚棋子,则最后应该剩的是7号。即本题答案为7号。