1. 程式人生 > >Problem E: 用連結串列實現約瑟夫環

Problem E: 用連結串列實現約瑟夫環

Description

你聽說過約瑟夫問題嗎?問題大致如下:首先n個人圍成一個圈,標記為1到n號。接著,從1號開始報數(從1開始),然後2號報數,然後3號。。。當有人報到到m時,這個人就要踢出比賽,然後從被踢出的人的下一個人開始,重新報數(從1開始)。這樣經過n-1次後,就只剩下了一個人,問最後剩下的那個人是幾號?

 

Input

第1行為T,表示有T組資料;

第2行到第T+1開始,每行輸入n和m,n表示有幾個人,m為上述的每報數m次就要踢出一個人

1=<n<=100, 1=<m<=100

 

Output

一個數,表示最後剩下了幾號     

 

Sample Input

2
5 3
6 4

Sample Output

4
5
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int number;
struct node * next;
}person;//結點型別 
person * list(int n)
{
    person * head=(person*)malloc(sizeof(person));
    head->number=1;
    head->next=NULL;
    person 
* cyclic=head; for (int i=2; i<=n; i++) { person * body=(person*)malloc(sizeof(person)); body->number=i; body->next=NULL; cyclic->next=body; cyclic=cyclic->next; } cyclic->next=head;//首尾相連 return head; } void find_delete(person * head,int
m)//此步我是將刪除和遍歷寫在一起的,可分開 { person * tail=head; //找到連結串列第一個結點的上一個結點,為刪除操作做準備 while (tail->next!=head) { tail=tail->next; } person * p=head; //找到編號為1的人 while (p->number!=1) { tail=p; p=p->next; } //從編號為1的人開始,只有符合p->next==p時,說明連結串列中除了p結點,所有編號都出列了, while (p->next!=p) { //找到從p報數1開始,報m的人,並且還要知道數m-1的人的位置tail,方便做刪除操作。 for (int i=1; i<m; i++) { tail=p; p=p->next; } tail->next=p->next;//從連結串列上將p結點摘下來 free(p); p=tail->next;//繼續使用p指標指向出列編號的下一個編號,比賽繼續 } printf("%d\n",p->number); free(p); } int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); person * head=list(n); int m; scanf("%d",&m); find_delete(head,m); } return 0; }