小言_互联网的博客

约瑟夫环问题(数组和循环链表)

497人阅读  评论(0)

问题描述
有编号问1~n个人按顺时针方向围坐一圈,每个人都持有一个密码(正整数)。一开始任选一个数m,从编号为1的人开始按顺序报数,数到m时停止报数,数到m的人出列,并将他的密码作为新的m值继续报数,直到所有人都出列为止。
思路分析
假设给定一组n=7个人分别持有的密码3,1,7,2,4,8,4.m初始值为6.从第一个人开始,数到6,8出列,并且m=8,继续从下一个人从1开始报数,数到8(此时密码为8的人已出列,故无需再报数)的人出列,将其密码替换m值…直到所有人出列为止。
很显然这是一道模拟题,我们只需要模拟报数,出列的过程即可,可想到利用循环链表实现或数组实现
实现过程

#include<bits/stdc++.h>

using namespace std;
struct node
{
    int num;		//定义编号
    int del;		//定义密码
    node *next;		//定义一个指向下一结构体的指针
};
int main()
{
    int n,m;
    node *p,*q,*first;		//定义指向结构体的指针
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        if(i==1)		
        {
            first=p=(node*)malloc(sizeof(node));
            if(p==0)
                return 0;
        }
        else
        {
            q=(node*)malloc(sizeof(node));
            if(q==0)
                return 0;
            p->next=q;
            p=q;
        }
        cin>>(p->del);
        p->num=i;
    }
    p->next=first;		//尾部指针指向第一个结构体,连接构成循环链表
    p=first;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<m;j++)		//模拟报数过程
            p=p->next;
        m=p->del;		//报到m的人出列,将其密码赋值为新的m值
        cout<<p->num<<" ";		//打印出列人的编号
        p->num=p->next->num;		//模拟出列过程
        p->del=p->next->del;
        q=p->next;
        p->next=p->next->next;
        free(q);
    }
    cout<<endl;
    return 0;
}

数组实现:这里只用到了一个数组,如出列删除数组中的元素则涉及到移位,会增加代码的复杂程度,这里通过数组下标也可达到相同效果。

#include<bits/stdc++.h>
using namespace std;
int a[35];
int main()
{
    memset(a,0,sizeof(a));
    int n,m;
    cin>>n>>m;
    for(int i=0; i<n; i++)
        cin>>a[i];
    int cnt=1,j=-1;		//cnt为出列次数,j控制数组下标
    while(cnt<=n)
    {
        int i=0;		//控制报数次数
        while(1)
        {
            j=(j+1)%n;
            if(a[j]>=0)
                i++;
            if(i==m)
            {
                cnt==n?cout<<j+1<<endl:cout<<j+1<<" ";
                m=a[j];
                a[j]=-1;		//通过改变出列值为负数模拟出列过程
                cnt++;
                break;
            }
        }
    }
    return 0;
}

小编有话说
本人还是一个资历尚浅正在学习编程的小白,如发现本文有何不妥之处,欢迎各位留言指出,我一定虚心接受。


转载:https://blog.csdn.net/q614701220/article/details/102411787
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场