这道题目的意思就是:假如输入3,那么就代表有6个人,然后1,2,3是好人,5,6,7就是坏人
前面一半是好人,后面一半是坏人。然后你要指定一个m,m代表的意思就是你要隔多少个人杀一次人,然后m必须满足,第一个好人,也就是1 必须在所有坏人被杀之后才能杀。说白了就是5,6,7死完了,1才可以死。你的目标是找到那个最小的m
思路如下
1.先来看一个josefu简单代码的实现(核心思想就是找到current 然后pop(current)) 下面的例子就是我分析题目用的例子
#encoding=utf-8
def josefu(n,k):
#n表示总人数 k表示每次杀人的间隔
#准备一个porple列表存储n个人
people=list(range(1,n+1))
#current表示数到哪儿来了,值得注意的就是crrent是数组下标所以要从0开始
current=0
while len(people)>1:
#计算出下一个被杀的人的位置
current=(current+k-1)%len(people)
#根据current杀人
people.pop(current)
return people[0]
print(josefu(6,5))
2.根据题目的意思就是,1肯定只能在后半个k中死,如果前半个k中出现1肯定就不对,那就不需要再继续判断了(用这个条件可以减少一点时间)
3.我的大体思路就是从0开始枚举m,然后利用josefu把每次杀的人记录下来,只要把后k个人都枚举了,而且这个时候1还没死,最先出现这种情况对应的m就是我们要找的那个m
4.只要把后k个人都枚举了,而且这个时候1还没死(再准备一个坏人列表存储k个人,每杀一个人如果是坏人就pop一个直到为空,就停止杀人返回m)(同时准备一个好人列表存k个好人,保证在坏人k列表为空之前,1没有被pop出去就ok了)
#encoding=utf-8
def josefu(n,k):
#n表示总人数 k表示每次杀人的间隔
#准备一个porple列表存储n个人
people=list(range(1,n+1))
#current表示数到哪儿来了,值得注意的就是crrent是数组下标所以要从0开始
current=0
while len(list_badman)>0:
#计算出下一个被杀的人的位置
current=(current+k-1)%len(people)
#根据current杀人
killed=people.pop(current)
if killed in list_goodman:
return False
if killed in list_goodman:
list_goodman.remove(killed)
else:
list_badman.remove(killed)
if len(list_badman)==0 and 1 in list_goodman:
return True
else:
return False
#主体程序
k=int(input())
#准备好人和坏人列表
list_goodman=[]
list_badman=[]
for i in range(1,k+1):
list_goodman.append(i)
for i in range(k+1,2*k+1):
list_badman.append(i)
m=1
while True:
if josefu(2*k,m):
print(m)
break
else:
m+=1
很烦 尽管已经给出erro了但是还是不知道到底错哪了,明天再想
搞个半天是我题目理解错了,按照我自己的题目的理解的意思就是:
#encoding=utf-8
def josefu(n,k):
# 准备好人和坏人列表
list_goodman = []
list_badman = []
for i in range(1, int(n/2 + 1)):
list_goodman.append(i)
for i in range(int((n/2) + 1), int(2 * (n/2) + 1)):
list_badman.append(i)
#n表示总人数 k表示每次杀人的间隔
#准备一个porple列表存储n个人
people=list(range(1,n+1))
#current表示数到哪儿来了,值得注意的就是crrent是数组下标所以要从0开始
current=0
while len(list_badman)>0:
#计算出下一个被杀的人的位置
current=(current+k-1)%len(people)
#根据current杀人
killed=people.pop(current)
if killed==1:
return False
if killed in list_goodman:
list_goodman.remove(killed)
else:
list_badman.remove(killed)
if len(list_badman)==0 and 1 in list_goodman:
return True
else:
return False
#主体程序
k=int(input())
m=1
while True:
if josefu(2*k,m):
print(m)
break
else:
m+=1
这个代码按照我对题目的意思就是正确的,明天再仔细看看题目到底是什么意思
题目的意思应该是:前k个被杀的都是坏人,那不就简单了。。。
#encoding=utf-8
def josefu(n,k):
# 准备好人和坏人列表
list_goodman = []
list_badman = []
for i in range(1, int(n/2 + 1)):
list_goodman.append(i)
for i in range(int((n/2) + 1), int(2 * (n/2) + 1)):
list_badman.append(i)
#n表示总人数 k表示每次杀人的间隔
#准备一个porple列表存储n个人
people=list(range(1,n+1))
#current表示数到哪儿来了,值得注意的就是crrent是数组下标所以要从0开始
current=0
while len(list_badman)>0:
#计算出下一个被杀的人的位置
current=(current+k-1)%len(people)
#根据current杀人
killed=people.pop(current)
if killed in list_goodman:
return False
else:
list_badman.remove(killed)
return True
#主体程序
k=int(input())
m=1
while True:
if josefu(2*k,m):
print(m)
break
else:
m+=1
上面这段代码就是正确答案