约瑟夫问题是一个经典的问题(大一我们讲过)。这个问题可以用数组,也可以用链表。作为复习,大家可以试试你自己的算法。
已知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
#include<stdio.h>
#include<stdlib.h>
struct node
{
int num;
struct node *next;
};
typedef struct node NODE;
typedef struct node * PNODE;
main()
{
int k,m,n,i,j,flag = 1,t;
PNODE head, p, q;
head = ( PNODE )malloc( sizeof( NODE ) );
head -> num = -2;
head -> next = head;
while(scanf("%d,%d,%d", &n, &k, &m )!=EOF)
{
getchar();
if( n <= 0 || k <= 0 || m <= 0 )
{
printf( "n,m,k must bigger than 0.\n" );
flag = 0;
}
if( k > n )
{
printf( "k should not bigger than n.\n" );
flag = 0;
}
if( flag == 1 )
{
for( i = n ; i > 0 ; i-- )
{
p = ( PNODE )malloc( sizeof( NODE ));
p -> next = head -> next;
p -> num = i;
head -> next = p;
}
while ( p -> next!=head )
p = p -> next;
p -> next = head -> next;
/*建立循环链表*/
for( i = 0; i < k; i++ )
p = p -> next;/*找出起始位置*/
for(i = 0; i < n ; i++)
{
for( j = 1; j < m; j++ )
p = p -> next;
q = p -> next;
p -> next = q -> next;
t = (q -> num) -1;/**/
if(t == 0)
t= t + n;
if(i < n - 1 && (i+1)%10!=0)
{
printf("%d ",t);
}
if( i == n -1 || (i+1)%10==0)
{
printf("%d\n",t);
}
free(q);/*报数找出剔除的人*/
}
}
}
}