题目描述:
给定m个人,从s开始报数,数字顺加,报到n的人出列,然后数字顺减报到k的人出列,求出列顺序
样例输入:
8 1 3 2
样例输出:
3 6 1 5 2 8 4 7
分析:
约瑟夫问题主要就是处理边界,因此选用链表,第一个指向最后一个,最后一个指向第一个。
注意,这里链表不用指针!不用指针!为什么?因为m<=100,链表节点数量小,可直接用数组+结构体!

q为前驱,h为后继。
完整代码如下:
#include <iostream>
#include <map>
#include <cstdio>
using namespace std;
int m,s,n,k,cnt,pd=true,pd2=true;
struct lb
{
int q,h;
}a[105];
void del(int x)//删除节点
{
a[a[x].q].h=a[x].h;
a[a[x].h].q=a[x].q;
}
int main()
{
// freopen("newjsf.in","r",stdin); //打开输入文件
// freopen("newjsf.out","w",stdout); //打开输出文件
cin>>m>>s>>n>>k;
a[1].q=m,a[1].h=2,a[m].q=m-1,a[m].h=1;
cnt=m;
for(int i=2;i<=m-1;i++)
{
a[i].q=i-1,a[i].h=i+1;
}
while(cnt>0)
{
if(pd)
for(int i=1;i<=n;i++)
{
if(pd2)//判断是否第一个人
{
pd2=false;
continue;
}
s=a[s].h;
}
else
for(int i=1;i<=k;i++) s=a[s].q;
cout<<s<<" ";
cnt--;
del(s);
}
fclose(stdin);//关闭输入文件
fclose(stdout);//关闭输出文件
}
原文:https://www.cnblogs.com/huaruoji/p/11729389.html