python3面试-将N(N<10000)个人排成一排,从第1个人开始报数;如果报数是M的倍数就出列...

面试题

某大厂迎来了新入职的大学生,现在需要为每个新同事分配一个工号。

人力资源部同事设计了一个方法为每个人进行排序并分配最终的工号,具体规则是:

将N(N<10000)个人排成一排,从第1个人开始报数;如果报数是M的倍数就出列,报到队尾(最后一位),则从头(回到对头)继续报,直到所有人都出列;最后按照出列顺序为每个人依次分配工号

思考

先出列,即将原数组中的该数字删除,先循环每位上的数字,和M除的尽,则出列;

如何维护原数列呢?若采用删除的办法,数列的长度会变,这样循环位置就不可以了,苦思冥想半天,无果;百度,维护原数列,采用切片的方式,终于ok;

先出列

假设10个人,报道3的倍数就出列

l=list(range(1,11))
n=3
newl=[]
while len(l)>=n:
    newl.append(l[n-1])
    l=l[n:]+l[:n-1]
print(l) #多余的
print(newl) #新数列

 运行结果:

[10, 4]
[3, 6, 9, 2, 7, 1, 8, 5]

 最后还剩2个人将继续报数;

人数小于n的情况

先循环[10,4],继续循环[10,4],此时10出列,剩余4; 

思考:所以当时采用减法,3-2=1,所以直接取列表的第1位;

           后面发现,若是剩余4位,取10的倍数,此方法就不可行,最后改为取余数;

l=list(range(1,11))
n=3
newl=[]
while len(l)>=n:
    newl.append(l[n-1])
    l=l[n:]+l[:n-1]
print(l) #多余的
print(newl) #新数列

while len(l)>1:#因为前面已经知道未分配的<out,不过为了保险起见,可以加上<的条件;
    a=n-len(l)
    newl.append(l[a-1])
    l=l[a:]+l[:a-1]
print(newl)
print(newl+l)

 练习:20个人,5的倍数出列

l=list(range(1,21))
newl=[]
out=5

while len(l)>=out:
    newl.append(l[out-1])
    l=l[out:]+l[:out-1] #切片左包,右不包
print(l) #剩余未被分配的
#print(newl) #新的排序

while len(l)>1:
    p=out%len(l)
    newl.append(l[p-1])
    l=l[p:]+l[:p-1]
print(l) #此时还剩余1个为分配
#print(newl) #新的排序
print(newl+l)#终极排序

 运行结果

[2, 7, 8, 14]
[7]
[5, 10, 15, 20, 6, 12, 18, 4, 13, 1, 9, 19, 11, 3, 17, 16, 2, 8, 14, 7]

 报数报到3的退出

100个人围成一圈编号1-100,一次开始报数,

从1开始,报到3的退出,然后继续从1开始,报到3的退出,直到最后只有2个人,得到编号?58, 91

从1开始,报到4的退出,然后继续从1开始,报到4的退出,直到最后只有3个人,得到编号? 

n为报到的数;

a=list(range(1,101))
n=4
while len(a)>=n:
    a=a[n:]+a[:n-1]
print(a)

 运行结果:

[97, 34, 45]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值