C++单向循环链表存储约瑟夫环

问题描述
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)按 顺时针方向围坐在一张圆桌周围,每个人持有一个密码(正整数)。一开始任选一个整数作为报数 上限值m,从第一个人开始顺时针自1报数,报到m时停止报数,报m的那个人出列,他的密码作为 新的m值,从他在顺时针方向上的下一个人又开始重新从1报数,报到m的那个人出列又出列;依此 规律重复下去,直到圆桌周围的人全部出列。

输入格式
第一行是一个整数,表示初始m值;
第二行一个数n,表示圆桌上做的人数
第三行是n个整数,表示圆桌上座客持有的密码

样例输入
20
7
3 1 7 2 4 8 4

样例输出
6 1 4 7 2 3 5

代码如下

#include 

using namespace std;

int a[100];
int m, n;

typedef struct Node
{
    int data;
    int id;
    struct Node *next;
}node, *linklist;

void creatLinklist(linklist &L)
{
    linklist p, q;

    L = new node();
    L->next = NULL;
    L->data = 0;  //设首节点密码为0

    p = L;

    for(int i = 0; i<n; i++)
    {
        q = new node();
        q->data = a[i];
        q->id = i+1;  //因为i从0开始
        q->next = NULL;

        p->next = q;
        p = q;
    }
    p->next = L;
}

void choose(linklist &L)
{
    linklist p, q;
    //p表示要出列元素的前驱,q表示要出列的元素
    p = L;
    q = L->next;
    int cnt = m;
    while(p)
    {
        //能取到
        if(cnt == 1 && q->data != 0)
        {
           p->next = q->next;  //改变后继
           cnt = q->data;  //改变密码
           cout<<q->id<<" ";  
           q = q->next;  //往后移动一个单位
        }
        //不能取到
        else
        {
            if(q->data != 0)  //跳过首节点
                cnt--;
            p = p->next;
            q = q->next;
        }
    }
}


int main()
{
    cin>>m>>n;
    for(int i = 0; i<n; i++)
        cin>>a[i];
    linklist L;
    creatLinklist(L);
    choose(L);
    //cout << "Hello world!" << endl;
    return 0;
}

你可能感兴趣的:(ACM,c语言入门,单向循环链表,约瑟夫环,C++,数据结构)