30.洗牌问题
http://acm.fzu.edu.cn/problem.php?pid=1062
因为一副牌中每张牌具有唯一性,因此使用递增数字代替每张牌构建给定2n长度的列表,然后按题目规则进行列表变化记录直到第一次恢复原来严格递增顺序时候的次数即可。但是这个方法面对较大的n时计算复杂度非常大。
def times(n):
li=[i for i in range(0,2*n)]
origin=li.copy()
ahead=li[:n] # 前半部分牌
behind=li[n:] # 后半部分牌
count=0
while True:
for i in range(0,n):
li[2*i+1]=ahead[i]
li[2*i]=behind[i]
count+=1
ahead=li[:n]
behind=li[n:]
if li==origin:
return count
# 第二种方法,通过观察,当第一张牌出现在第n+1的位置时,其下一次将回到原位。
# 第一张牌每次洗牌后所处的位置规律为:
# 当第一张牌位于前n个位置的时候,其下一次所在位置为当前位置的2倍处
# 当第一章牌位于后n个位置的时候,其下一次所在位置为当前位置的(idx-n)*2-1
def times_quick(n):
count=0
i=1
while i!=n+1:
if i<=n:
i*=2
else:
i=(i-n)*2-1
count+=1
return count+1
import sys
for read_in in sys.stdin:
if read_in:
print(times_quick(int(read_in.rstrip())))