C++解决约瑟夫问题,猴子称王,丢手绢问题(详细解释)

本文介绍了如何使用C++编程解决约瑟夫问题,即猴子选猴王的问题。通过创建一个表示猴子的数组并利用递推公式f[i]=(f[i-1]+m) mod i进行计算,最终找出猴王的编号。示例代码展示了具体的实现过程。
摘要由CSDN通过智能技术生成

约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。

描述:约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入:每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m, n < 300)。最后一行是: 0 0

输出:对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号

input:

6 2

12 4

8 3

0 0

output:

5

1

7

分析:猴子可以用一个数组来表示,数组的值为猴子的编号,当某只猴子出局即把该编号改为0

说明该猴子出局,当最后只剩下一个不为0的值时该值即为猴王编号。

百度可以看到详细推理过程,此处只给推出的递推公式

递推公式

f[1]=0;

f[i]=(f[i-1]+m) mod i; (i>1)

我们开始写程序吧。。。。

#include<iostream>
#include&l

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
约瑟夫环问题是一个经典的问题,可以用循环链表来解决。具体的解决方法如下: 1. 首先,创建一个长度为n的循环链表,并将链表中的节点编号从1到n。 2. 定义一个指针p,指向链表的第一个节点。 3. 定义一个计数器count,初始值为1。 4. 从链表中删除第count个节点,并将指针p指向下一个节点。 5. 将计数器count加1。 6. 重复步骤4和5,直到链表中只剩下一个节点。 7. 输出最后剩下的节点编号,即为约瑟夫环的解。 下面是C语言代码实现: ```c #include <stdio.h> #include <stdlib.h> typedef struct node { int num; struct node *next; } Node; Node *createList(int n) { Node *head = (Node *)malloc(sizeof(Node)); Node *p = head; for (int i = 1; i <= n; i++) { Node *node = (Node *)malloc(sizeof(Node)); node->num = i; p->next = node; p = node; if (i == n) { p->next = head->next; } } return head->next; } int josephus(int n, int m) { Node *head = createList(n); Node *p = head; while (p->next != p) { for (int i = 1; i < m - 1; i++) { p = p->next; } printf("%d ", p->next->num); Node *temp = p->next; p->next = temp->next; free(temp); p = p->next; } printf("%d\n", p->num); return p->num; } int main() { int n, m; scanf("%d%d", &n, &m); josephus(n, m); return 0; } ``` 在上面的代码中,我们首先定义了一个结构体Node,表示链表中的节点。然后,我们创建了一个长度为n的循环链表,并定义一个指针p,指向链表的第一个节点。接着,我们循环执行步骤4和5,直到链表中只剩下一个节点,输出该节点的编号即为约瑟夫环的解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值