BIT2018 DS-SS 約瑟夫問題與迴圈連結串列
阿新 • • 發佈:2018-12-15
約瑟夫問題是一個經典的問題(大一我們講過)。這個問題可以用陣列,也可以用連結串列。作為複習,大家可以試試你自己的演算法。
已知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);/*報數找出剔除的人*/ } } } }