(1):問題提出
設由n個人站成一個圈,分別編號1,2,3,4….n。從第一個人開始報數每次報數為m的人被從圈中推出,其后的人再次從1開始報數,重復上述過程, 直至所有人都從圈中退出。要求程序由用戶輸入整數m和n,求這n個人從圈中推出的先后順序。
(2):解決思路
可利用鏈表求解這個問題,先由n形成一個有n個表元組成的環,其中n個表元依次置值1~n。然后,從環的第一個表元出發,連續掠過m-1個表元,第m-1個表元的后繼表元是第m個表元,將該表元從環中退出。接著再次從下一個表元出發,重復以上過程,直至環中表元都退出為止。
(三):代碼實現
~~~
#include <stdio.h>
#include <stdlib.h>
/**
* 設由n個人站成一個圈,分別編號1,2,3,4....n。從第一個人開始報數
* 每次報數為m的人被從圈中推出,其后的人再次從1開始報數,重復上述過程,
* 直至所有人都從圈中退出。要求程序由用戶輸入整數m和n,求這n個人從圈中
* 推出的先后順序。
*
*/
//定義一個循環鏈表
struct LinkedList{
int number;
struct LinkedList *next;
};
//輸出鏈表
void print(struct LinkedList *ll){
struct LinkedList *current = ll;
do{
printf("%d\t",current->number);
current = current->next;
}
while(current != ll);
printf("\n");
}
int main()
{
int m,n;
int i;
printf("Please input the m and n(dividded by ','):\n");
scanf("%d,%d",&n,&m);
struct LinkedList *pre = (struct LinkedList *)malloc(sizeof(struct LinkedList));
struct LinkedList *current = pre;
current->number = 1;
//分配內存并賦值
for(i = 2;i <= n;i++){
current->next = (struct LinkedList *)malloc(sizeof(struct LinkedList));
current = current->next;
current->number = i;
}
current->next = pre;
pre = current;
while(n){
for(i = 1; i < m;i++) //忽略那些沒用的
pre = pre->next;
current = pre->next;
printf("%d\t",current->number); //打印出相關信息
pre->next = current->next; //刪除打印出的信息
free(current);
n--;
}
return 0;
}
~~~
(四):相關知識
下面是我定義的一個關于循環鏈表的代碼,大家可以看一下:
~~~
#include <stdio.h>
#include <stdlib.h>
//越界
#define OUT 0
//成功
#define SUCCESS 1
/**
* 設由n個人站成一個圈,分別編號1,2,3,4....n。從第一個人開始報數
* 每次報數為m的人被從圈中推出,其后的人再次從1開始報數,重復上述過程,
* 直至所有人都從圈中退出。要求程序由用戶輸入整數m和n,求這n個人從圈中
* 推出的先后順序。
*
*/
//定義一個循環鏈表
struct LinkedList{
int number;
struct LinkedList *next;
};
//鏈表初始化
struct LinkedList * initLL(struct LinkedList *ll){
ll = (struct LinkedList *)malloc(sizeof(struct LinkedList));
ll->next = ll;
return ll;
}
//判斷循環鏈表是否為空
int isEmpty(struct LinkedList *ll){
return ll->next == ll ? 1 : 0;
}
//返回鏈表中元素的個數
int size(struct LinkedList *ll){
struct LinkedList *current = ll;
int count = 0;
while(current->next != ll){
current = current->next;
count++;
}
return count;
}
//向鏈表中添加一個元素
void add(struct LinkedList *ll,int data){
struct LinkedList *temp = ll;
while(temp->next != ll)
temp = temp->next;
struct LinkedList *llAdd = (struct LinkedList *)malloc(sizeof(struct LinkedList));
llAdd->number = data;
temp->next = llAdd;
llAdd->next = ll;
}
//向指定位置添加元素
//即在position之后添加一個元素
int insert(struct LinkedList *ll,int position,int data){
if(size(ll) < position)
return OUT;
int i = 0;
struct LinkedList *temp = ll;
for(i = 0;i < position;i++){
temp = temp->next;
}
struct LinkedList *llAdd = (struct LinkedList *)malloc(sizeof(struct LinkedList));
llAdd->number = data;
llAdd->next = temp->next;
temp->next = llAdd;
return SUCCESS;
}
//刪除指定位置的元素
int removeAt(struct LinkedList *ll,int position){
if(size(ll) < position)
return OUT;
struct LinkedList *current = ll;
struct LinkedList *pre ;
int i = 0;
for(i = 0;i < position;i++){
pre = current;
current = current->next;
}
//data = current->number;
printf("%d\t",current->number);
pre->next = current->next;
free(current);
return SUCCESS;
}
//輸出鏈表
void print(struct LinkedList *ll){
struct LinkedList *current = ll->next;
while(current != ll){
printf("%d\t",current->number);
current = current->next;
}
printf("\n");
}
~~~
(五):運行結果
下面是程序的運行結果:

- 前言
- 實例一:HelloWorld
- scanf函數學習
- 實數比較
- sizeof()保留字獲取類型的大小
- 自增/自減學習
- C學習if條件判斷和for循環
- C實現的九九乘法表
- C實現一個比較簡單的猜數游戲
- 使用C模擬ATM練習switch..case用法
- 記錄一個班級的成績練習一維數組
- C數組實現矩陣的轉置
- C二維數組練習
- 利用數組求前n個質數
- C實現萬年歷
- C實現數組中元素的排序
- C實現任意進制數的轉化
- C判斷一個正整數n的d進制數是否是回文數
- C使用遞歸實現前N個元素的和
- 鋼材切割問題
- 使用指針比較整型數據的大小
- 指向數組的指針
- 尋找指定元素
- 尋找相同元素的指針
- 整數轉換成羅馬數字
- 字符替換
- 從鍵盤讀入實數
- C實現字符行排版
- C實現字符排列
- C實例--判斷一個字符串是否是回文數
- 通訊錄的輸入輸出
- 撲克牌的結構定義
- 使用“結構”統計學生成績
- 報數游戲
- 模擬社會關系
- 統計文件中字符個數
- C實現兩個文件的內容輸出到同一個屏幕