标题
约瑟夫环
时间限制
2 S
内存限制
10000 Kb
问题描述
编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。现在给定一个随机数m>0,从编号为1的人开始,按顺时针方向1开始顺序报数,报到m时停止。报m的人出圈,同时留下他的密码作为新的m值,从他在顺时针方向上的下一个人开始,重新从1开始报数,如此下去,直至所有的人全部出圈为止。试设计程序求解出列顺序。
问题输入
输入数据第一行为两个正整数n和m,分别表示人的个数及初始随机数,每组数据的第二行为n个整数,表示每个人持有的密码。
问题输出
用一行输出n个整数表示依次出圈人的编号,整数之间用空格分隔。
输入样例
7 20
3 1 7 2 4 8 4
输出样例
6 1 4 7 2 3 5
提示
使用不带头节点的循环链表。
# include <stdio.h>
# include <malloc.h>
typedef struct LNode
{
int data;
int cha = 0;
int Lnum;
struct LNode * next;
}LNode, *LinkList;
void Add(LinkList * LTail, int data, int i)
{
LinkList LNew = (LinkList)malloc(sizeof(LNode));
LNew->data = data;
LNew->Lnum = i;
if (*LTail == NULL)
{
LNew->next = LNew;
*LTail = LNew;
}
else
{
LNew->next = (*LTail)->next;
(*LTail)->next = LNew;
(*LTail) = LNew;
}
}
int main(void)
{
int n = 0, num = 0, j = 0;
int a[20] = {0};
scanf("%d %d", &n, &num);
LinkList LTail = 0;
for (int i = 1; i <= n; i++)
{
int data = 0;
scanf("%d", &data);
Add(<ail, data, i);
}
LinkList LNow = LTail->next;
num-=1;
while (j < n)
{
if (LNow->cha != 1)
{
if (num != 0)
{
num--;
LNow = LNow->next;
}
else
{
LNow->cha = 1;
a[j++] = LNow->Lnum;
num = LNow->data-1;
}
}
else
{
LNow = LNow->next;
}
}
for (int i = 0; i<n; ++i)
{
printf("%d ", a[i]);
}
return 0;
}