1. 程式人生 > >BIT2018 DS-SS 約瑟夫問題與迴圈連結串列

BIT2018 DS-SS 約瑟夫問題與迴圈連結串列

約瑟夫問題是一個經典的問題(大一我們講過)。這個問題可以用陣列,也可以用連結串列。作為複習,大家可以試試你自己的演算法。

已知n個人(不妨分別以編號1,2,3,…,n 代表 )圍坐在一張圓桌周圍,從編號為 k 的人開始,從1開始順時針報數1, 2, 3, ...,順時針數到m 的那個人,出列並輸出。然後從出列的下一個人開始,從1開始繼續順時針報數,數到m的那個人,出列並輸出,…依此重複下去,直到圓桌周圍的人全部出列。

輸入:n, k, m

輸出:按照出列的順序依次輸出出列人的編號,編號中間相隔一個空格,每10個編號為一行。

非法輸入的對應輸出如下

a)

輸入::nkm任一個小於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);/*報數找出剔除的人*/
				
				
		  	}
	    }
	}
}