约瑟夫问题

来源:互联网 发布:js 图片跟随鼠标移动 编辑:程序博客网 时间:2024/06/02 00:58

1.实验题目
约瑟夫(Joeph)问题的一种描述是:编号为 1,2,…,n 的 n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值 m,从第一个人开始按顺时针方向自 1 开始顺序报数,报到 m 时停止报数。报 m 的人出列,将他的密码作为新的 m 值,从他在顺时针方向上的下一个人开始重新从 1 报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
2.需求分析
利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
① 程序所能达到的功能:完成单向循环链表的建立,以及相应操作解决约瑟夫问题
② 测试数据:
m 的初值为 20;密码:3,1,7,2,4,8,4(正确的结果应为 6,1,4,7,2,3,5)

#include<iostream>#include<vector>using namespace std;typedef int  ElemType;typedef struct node{    ElemType psd;    int num;    node *next;} *LinkList;LinkList createlist(int n, vector<int> g){    LinkList l = new node;    node *p = l;    for (int i = 0; i<n-1; i++)    {        p->psd = g[i];        p->num = i+1;        p->next = new node;        p = p->next;    }    p->num = n;    p->psd = g[n - 1];    p->next = l;    return l;}void fun(LinkList &l1, int m){    node *a = l1;    node *b = a;    while (a->next != a)    {        while ((m--) - 1)        {            b = a;            a = a->next;        }        cout << a->num;        m = a->psd;//b是前驱结点        b->next = a->next;          node *c = a;        a = a->next;//删除目标结点        delete c;       }    cout << a->num;}vector<int> v;int main(){        int m;        cin >> m;    int password;    int n = 0;    while (cin >> password)    {        v.push_back(password);        n++;    }    LinkList CircleList = createlist(n, v);    fun(CircleList, m);    return 0;}
原创粉丝点击