蓝桥杯:约瑟夫环问题

试题 算法训练 报数

问题描述
  现有n个同学站成一圈,顺时针编号1至n。从1号同学开始顺时针1/2报数,报到1的同学留在原地,报到2的同学退出圆圈,直到只剩一名同学为止。问最后剩下的同学编号。
输入格式
  仅一行,一个正整数n。
输出格式
  仅一行,一个正整数。
样例输入
400
样例输出
289
数据规模和约定
  n<=2000000

 

1,链表

import ipdb

class Dnode:
    def __init__(self, value, prev=None, nxt=None):
        self.val = value
        self.prev = prev
        self.next = nxt


def delete(one):
    one.prev.next = one.next
    one.next.prev = one.prev 

if __name__ == '__main__':
    
    #n = input()
    n = 400 
    head = None
    pre, nxt = None, None
    for i in range(1, n+1):
    
        if not pre:
            pre = Dnode(i)
            head = pre 
        else:
            nxt = Dnode(i, prev=pre)
            pre.next = nxt 
            pre = nxt 
            nxt = None
    head.prev = pre 
    pre.next = head


    tmp = head
    flag = True
    while tmp.next:
        print(tmp.val)
        flag = bool(1-flag)
        if flag:
            delete(tmp)
            print('del:', tmp.val)
        tmp = tmp.next
        if tmp.next == tmp:
            print(tmp.val)
            break

2, 暴力法


import ipdb

if __name__ == '__main__':
    
    #n = input()
    n = 400 
    
    pp = [i for i in range(1, n+1)]
  
    idx, cnt = 0, 0
    flag = True 
    while True:

        flag = bool(1-flag)
        if flag:
            pp[idx] = 0 
            cnt += 1 
            if cnt == n-1:
                break

        idx = (idx+1)%n
        while not pp[idx]:
            idx = (idx+1)%n

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值