猴子选大王

本文介绍了如何使用链表数据结构解决猴子选大王的数学问题,通过报数和出局规则模拟,最终找出最后的大王。算法包括创建节点、添加节点和猴子选王函数的实现。
摘要由CSDN通过智能技术生成
猴子选大王是一道经典的数学问题。问题描述如下 : N 只猴子围成一圈,依次编号为
1,2,.3.….N 。从 1 号猴子开始依次报数,报到 M 的猴子出局。出局的猴子不再参与报数,下
一个猴子从 1 开始重新报数。如此循环,直到只剩下 只猴子为止,这只猴子即为大王。例
如,当 N=5 M=3 时,猴子出局的顺序为 :3,1,5,2 ,最后剩下的猴子编号为 4 ,所以 4 号猴子
是大王。
这道题确实是有点难,属于上机题中比较难的那一道题,用链表来实现,但是考试的时候我可能想不到,但是会有步骤分。
1.先引入库函数

#include <stdio.h>
#include <stdlib.h>

2.构建链表

// 链表节点定义
typedef struct Node {
    int number;    // 猴子的编号
    int status;    // 1表示在圈内,0表示出局
    struct Node *next;
} Node;

3.创建新节点的函数
Node* createNode(int number) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->number = number;
    newNode->status = 1; // 默认在圈内
    newNode->next = NULL;
    return newNode;
}

4.向链表末尾添加新节点的函数
void addNode(Node** head, int number) {
    Node* newNode = createNode(number);
    if (*head == NULL) {
        *head = newNode; // 如果链表为空,新节点即为头节点
    } else {
        Node* current = *head;
        while (current->next != NULL) {
            current = current->next; // 移动到链表末尾
        }
        current->next = newNode; // 在末尾添加新节点
    }
}

5.定义功能函数

// 猴子选大王的函数
Node* findMonkeyKing(int N, int M) {
    Node* head = NULL; // 初始化链表为空
    // 创建链表
    for (int i = 1; i <= N; i++) {
        addNode(&head, i);
    }
    
    Node* current = head; // 从头节点开始报数
    while (head->next != head) { // 当链表长度大于1时继续报数
        for (int count = 1; count < M; count++) {
            current = current->next; // 报数到M-1
        }
        // 报到M的猴子出局
        if (current->status == 1) {
            current->status = 0; // 猴子出局
            head = current->next; // 移除出局猴子
            free(current); // 释放内存
            current = head; // 重新从头节点开始报数
        } else {
            current = current->next; // 移动到下一个节点
        }
    }
    // 返回最后剩下的小王的节点
    return head;
}

6.主函数依旧是  定义输入 输入并接受 调用主函数  输出

// 主函数
int main() {
    int N, M;
    printf("请输入猴子的数量N和报数M:");
    scanf("%d %d", &N, &M);
    
    Node* king = findMonkeyKing(N, M);
    printf("最后剩下的猴子的编号为:%d\n", king->number);
    
    // 释放链表内存
    Node* current = king;
    Node* next;
    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }
    
    return 0;
}

这道题的确优点难度,有没有哪位大神有更好的思路?
 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值