7-5 约瑟夫环 (25 分)
N个人围成一圈顺序编号,从1号开始按1、2、3…顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。 请按退出顺序输出每个退出人的原序号。
输入格式:
输入只有一行,包括一个整数N(1<=N<=3000)及一个整数p(1<=p<=5000)。
输出格式:
按退出顺序输出每个退出人的原序号,数据间以一个空格分隔,但行尾无空格。
输入样例:
在这里给出一组输入。例如:
7 3
结尾无空行
输出样例:
3 6 2 7 5 1 4
结尾无空行
1.1 解题思想
约瑟夫环问题可以转化为循环链表的数据结构来求解。可以将每个人看做链表的单个节点,每个节点之间通过链表的 next 指针连接起来,并且将链表末尾节点指向头节点就形成的环,由链表构成的环形结构在数据结构中称为循环链表。
1.2 代码实现
#include<iostream>
using namespace std;
typedef int Elemdata;
typedef struct node {
Elemdata data;
struct node* next;
}Node,*Linklist;
void creatlist(Linklist& L, int n)
{
L = new Node;
L->next = NULL;
Linklist p,r;
r = L;
for (int i = 1; i <= n; i++) {
p = new Node;
p->data = i;
p->next = NULL;
r->next = p;
r = p;
}
r->next = L->next;
}
void Joseph(int n, int m)
{
Linklist L, q,p;
creatlist(L,n);
Elemdata i;
p = L->next;
while (p->next != p)//循环条件,当前链表数目大于1
{
for (i = 1; i < m - 1; i++)//开始计数
{
p = p->next;
}
//第m个人出圈
q = p->next;
p->next = q->next;
p = p->next;
cout << q->data << " ";
}
cout << p -> data<<endl;
/*while (L->next != L)
{
cout << L->data << " ";
L = L->next;
}*/
}
int main() {
Elemdata n, m;
//scanf_s("&d &d",&n,&m);
cin >> n >> m;
Joseph(n, m);
return 0;
}