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;
}
