约瑟夫问题是一个经典的问题。已知n个人(不妨分别以编号1,2,3,…,n 代表 )围坐在一张圆桌周围,从编号为 k 的人开始,从1开始顺时针报数1, 2, 3, ...,顺时针数到m 的那个人,出列并输出。然后从出列的下一个人开始,从1开始继续顺时针报数,数到m的那个人,出列并输出,…依此重复下去,直到圆桌周围的人全部出列。
输入:n, k, m
输出:按照出列的顺序依次输出出列人的编号,编号中间相隔一个空格,每10个编号为一行。
非法输入的对应输出如下
a)
输入::n、k、m任一个小于1
输出:n,m,k must bigger than 0.
b)
输入:k>n
输出:k should not bigger than n.
例:
输入:9,3,2
输出:4 6 8 1 3 7 2 9 5
测试输入![]() | 期待的输出![]() | 时间限制![]() | 内存限制![]() | 额外进程![]() | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
测试用例 2 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
#include <stdio.h>
#include <stdlib.h>
struct node
{
int banngou; //番号
struct node* next;
};
typedef struct node human;
int main()
{
int n,k,m; //输入
int i,j,l;
scanf("%d,%d,%d",&n,&k,&m);
while(1)
{
if(n<1||k<1||m<1)
{
printf("n,m,k must bigger than 0.\n");
break;
}
if(k>n)
{
printf("k should not bigger than n.\n");
break;
}
human *head,*p,*out;
head=(human*)malloc(sizeof(human));
head->banngou=-1;
head->next=head; //建立循环空表
for(i=n;i>0;i--) //插入全部结点
{
p=(human*)malloc(sizeof(human));
p->next=head->next;
p->banngou=i;
head->next=p;
}
while(p->next!=head) //使p为head前一个结点
p=p->next;
p->next=head->next; //形成抛弃head的循环链表
p=p->next; //此时p为第一个结点
for(i=0;i<k-2;i++) p=p->next; //此时p为第k-1个结点
for(j=1;j<n+1;j++)
{
for(l=0;l<m-1;l++) p=p->next; //此时p为报m-1的结点
out=p->next; //标记要出列的结点(报m的结点)
p->next=out->next; //跳过要出列的结点
printf("%d",out->banngou);
free(out);
if((j==n)||(j%10==0)) printf("\n");
else printf(" ");
}
break;
}
return 0;
}