2032 猴子選大王
Description
有N只猴子,從1~N進行編號。它們按照編號的順時針方向排成一個圓圈,然后從第一只猴子開始報數。第一只猴子報的第一個數字為1,以后每只猴子報的數字都是它們前面猴子所報數字加1。如果一個猴子報的數字是M,則該猴子出列,下一個猴子重新從1開始報數,直到所有猴子都出列為止,最后一個出列的猴子勝出。你的任務是對於給定猴子數量和報數上限值M,確定出能夠被選作大王的猴子的編號。
Input
第一行為一個整數N,表示測試數據的組數,接下來的N行中每行包含兩個整數,第一個數是猴子的個數,第二個數是報數上限值M(M>1),兩數之間由空格分隔。
Output
輸出共N行,每行為對應輸入行獲勝猴子的編號。
Sample Input
2
8 5
5 8
Sample Output
3
1
#include <stdio.h> #include <stdlib.h> /* 定義鏈表節點類型 */ typedef struct node { int data; struct node *next; }linklist; int creat(int n, int m) { linklist *head, *p, *s, *q; int i, total; /* 創建循環鏈表,頭節點也存信息 */ head = (linklist*) malloc(sizeof(linklist)); p = head; p->data = 1; p->next = p; /* 初始化循環鏈表 */ for (i = 2; i <= n; i++) { s = (linklist*) malloc(sizeof(linklist)); s->data = i; s->next = p->next; p->next = s; p = p->next; } p = head; /* 保存節點總數 */ total = n; q = head; /* 只剩一個節點時停止循環 */ while (total != 1) { /* 報數過程,p指向要刪除的節點 */ for (i = 1; i < m; i++) { p = p->next; } /* q 指向 p 節點的前驅 */ while (q->next != p) { q = q->next; } /* 刪除 p 節點 */ q->next = p->next; /* 保存被刪除節點指針 */ s = p; /* p 指向被刪除節點的后繼 */ p = p->next; /* 釋放被刪除的節點 */ free(s); /* 節點個數減一 */ total--; } //free(p); /* 打印最后剩下的節點序號 */ int vsdata=p->data; free(p); return vsdata; } int main() { int n[10], m[10]; /* 讀入問題條件 */ int k; scanf("%d", &k); for (int i=0;i<k;i++) { scanf("%d%d",&n[i],&m[i]); } for (int ii=0;ii<k;ii++) { printf("%d\n",creat(n[ii],m[ii])); } return 0; }