Josephus问题求解

今天徒弟问了我这样的一个问题,当时想了很久才把他解决了。其实也不是什么很难得问题,主要是自己的思维被局限了。被局限到那些所谓的库了,比如STL什么的了。所以一时没有想到什么好办法,后来才想到用循环链表去解决它。

下面就来学习下这个问题吧。
编号为1 ,2 ,3 …..,n的n个人按顺时针方向围坐成一圈,每个人持有一个密码,现在给定一个随机数m> 0 , 从编号为1的热开始,按照顺时针顺序从1开始报数。报到m时停止,报m的人出去,同时留下密码作为新的随机数,然后从他的下一个开始重新从1技术,如此下去,直到所有的人全部出来为止。

具体代码其实是很简单的。下面就来看下吧。唯一的难点就是循环链表的遍历。

#include <iostream>

using namespace std;

/*人物的定义,包含自己的编号,所持的密码,和指向下一个的指针*/

struct Person
{
        int num;
        int cipher;
        Person * next;
};

Person person[7];



int  main()

{

        //先对所有的属性赋值
        for (int i = 0; i<7; i++)
        {
            person[i].num = i + 1;
            person[i].next = &person[i + 1];
        }
        person[6].next = &person[0];//使最后一个人物的指针指向第一个,构成循环链表
        person[0].cipher = 3;
        person[1].cipher = 1;
        person[2].cipher = 7;
        person[3].cipher = 2;
        person[4].cipher = 4;
        person[5].cipher = 8;
        person[6].cipher = 4;



        int m = 20;//开始时输入的起始密码值

        Person * currentPerson;//方便对人物链表的搜索
        Person * prePerson;

        currentPerson = &person[0];//开始时将指针指向人物的第一个和最后一个,因为是循环链表
        prePerson = &person[6];

        while (currentPerson != prePerson)
        {
            for (int i = 1; i<m; i++)//移动指针,使其指向需要移出的人物,如果m = 7,就需要执行6次操作,所i从1开始的,而不是0开始的
            {

                    prePerson = currentPerson;
                    currentPerson = currentPerson->next;

            }

                m = currentPerson->cipher;
                cout << currentPerson->num << "  ";//输出人物的编号
                prePerson->next = currentPerson->next;//修改链表,使选定的人物移出
                currentPerson = prePerson->next;

        }

        cout << currentPerson->num;//输出最后一个人物的编号

        getchar();

        return 0;

}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值