Josephus
问题描述:编号为1,2,…,n的n个人按顺时针方向围坐在一张圆桌周围,每人持有一个密码(正整数)。一开始任选一个正整数m作为报数上限值,从第一个人开始按顺时针方向自1开始报数,报到m时停止报数,报m的那个人出列,将他的密码作为新的m值,从他顺时针方向的下一个人开始重新从1报数,数到m的那个人又出列;如此下去,直至圆桌周围的人全部出列为止。要求按出列顺序输出n个人的编号。
输入格式:
第一行输入两个整数,依次表示人数n和初始化密码m,以空格间隔。 第二行依次输入n个整数,分别表示n个人的密码,以空格间隔。
输出格式:
按出列次序输出每个人的编号,以空格间隔。
输入样例:
在这里给出一组输入。例如:
7 20
3 1 7 2 4 8 4
输出样例:
在这里给出相应的输出。例如:
6 1 4 7 2 3 5
/思路:循环链表,循环移动结点,找到后删除结点,继续寻找,直至所有结点都被找过/
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int num, password;
struct node *next;
}*Linklist;
Linklist H,r,s;
//创建循环链表
void Creat_Tlinklist(int n)
{
H = (Linklist)malloc(sizeof(Linklist));
r = H;
int i;
int x;
for (i = 1; i < n;i++)
{
s = (Linklist)malloc(sizeof(Linklist));
r->next = s;
r = s;
}
r->next = H;
s = H;
}
void input_Linklist(int n)
{
int x;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
s->password = x;
s->num = i;
s=s->next;
}
s = r;
}
//输出并出列
void Output_Linklist(int n,int m)
{
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <m;j++)
s = s->next;//找到结点
r = s->next;
m = r->password;
printf("%d ", r->num);
s->next = r->next;
free(r);
}
}
//主函数
int main()
{
int n, m;
scanf("%d %d", &n, &m);
Creat_Tlinklist(n);
input_Linklist(n);
Output_Linklist(n, m);
return 0;
}
问题二
编号为1,2,…,n的n个人按顺时针方向围坐在一张圆桌周围。给定一个正整数m≤n,从第一个人开始按顺时针方向自1开始报数,每报到m时就让其出列,从 他顺时针方向的下一个人开始重新从1报数,数到m的那个人又出列。如此下去,直至圆桌周围的人全部出列为止。每个人的出列次序定义了整数1,2,3,…,n的一个排列。这个 排列称为一个(n,m)Josephus排列。例如:(7,3)Josephus排列为3,6,2,7,5,1,4。
输入格式:
输入两个整数,人数n和密码m,以空格间隔。
输出格式:
按出列次序输出每个人的编号,以空格间隔。
输入样例:
在这里给出一组输入。例如:
7 3
输出样例:
在这里给出相应的输出。例如:
3 6 2 7 5 1 4
/思路:和上题一样不过这次不需要提供密码,也就是循环一致,其实我们把上题中所有有关密码的操作全部去掉就可以了/
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int num;
struct node *next;
}*Linklist;
Linklist H,r,s;
//创建循环链表
void Creat_Tlinklist(int n)
{
H = (Linklist)malloc(sizeof(Linklist));
r = H;
int i;
for (i = 1; i < n;i++)
{
s = (Linklist)malloc(sizeof(Linklist));
r->next = s;
r = s;
}
r->next = H;
s = H;
}
void input_Linklist(int n)
{
for(int i=1;i<=n;i++)
{
s->num = i;
s=s->next;
}
s = r;
}
//输出并出列
void Output_Linklist(int n,int m)
{
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <m;j++)
s = s->next;//找到第i-1个结点
r = s->next;
printf("%d ", r->num);
s->next = r->next;
free(r);
}
}
//主函数
int main()
{
int n, m;
scanf("%d %d", &n, &m);
Creat_Tlinklist(n);
input_Linklist(n);
Output_Linklist(n, m);
return 0;
}
以上代码仅供参考,有问题希望大佬指正!!!