当前位置: 首页 > news >正文

约瑟夫环问题——4个解法总结(C语言)

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

样例输入

6 2

样例输出

5

样例输入

12 4

样例输出

1

1.循环链表实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>typedef struct link
{int data;link* next;
}link;int main()
{int n, m;int i;printf("请输入(n/m):");scanf("%d%d", &n, &m);link* head = (link*)malloc(sizeof(link));//头节点head->data = -1;head->next = NULL;link* tail, * p, * q;tail = head;//构造循环节点for (i = 0; i < n; i++){p = (link*)malloc(sizeof(link));p->data = i + 1;tail->next = p;p->next = head->next;tail = p;}p = head->next;//p为要删除的那一个指针,q为p的前一个位置的指针q = tail;i = 1;//用i来报数while (p != q)//直到两个指针相同时,循环链表内除开头节点外只有一个节点了{if (i == m)//当报数为m时,删除p,同时让i=1{i = 1;q->next = p->next;free(p);p = q->next;}else{q = p;p = p->next;i++;}}printf("最后留下的猴子序号为: %d", p->data);free(p);free(head);return 0;
}

2.数组标志位实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>int main()
{int n, m;int i;int monkey[300] = { 0 };printf("请输入(n/m): ");scanf("%d%d", &n, &m);for (i = 0; i < n; i++){monkey[i] = i + 1;}int number = n;//记录此时数组中有效元素的个数int count = 1;//用来报数int pos = 0;//记录数组下标位置while (number > 1){if (monkey[pos] > 0){if (count == m){monkey[pos] = 0;count = 1;number--;pos = (pos + 1) % n;}else{count++;pos = (pos + 1) % n;}}elsepos = (pos + 1) % n;}for (i = 0; i < n; i++)if (monkey[i] > 0)printf("最后留下的猴子序号为:%d\n", monkey[i]);return 0;
}

3.数组模拟(循环)链表实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>int main()
{int n, m;int monkey[300] = { 0 };int i;printf("请输入(n/m): ");scanf("%d%d", &n, &m);for (i = 0; i < n - 1; i++)//数组模拟循环链表,数组的值相当于链表的next,指向下一个数组结点的下标{monkey[i] = i + 1;}monkey[i] = 0;int number = n;//记录当前数组有效元素个数int count = 1;//用来报数int pos = 0;int prior = n - 1;while (number > 1)//或者while(prior!=pos){if (count != m){count++;prior = pos;pos = monkey[pos];}else{monkey[prior] = monkey[pos];monkey[pos] = -1;pos = monkey[prior];count = 1;number--;}}printf("最后留下的猴子序号为:%d\n", pos + 1);return 0;
}

4.数学方法(原理自己百度查)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>int main()
{int n, m;printf("请输入(n/m):");scanf("%d%d", &n, &m);int pos = 0;for (int i = 2; i < n + 1; i++){pos = (pos + m) % i;}printf("最后留下的猴子序号为:%d\n", pos + 1);return 0;
}


http://www.mrgr.cn/news/64253.html

相关文章:

  • nodejs批量修改word文档目录样式
  • Unity简易版成就系统
  • kafka如何获取 topic 主题的列表?
  • web——upload1——攻防世界
  • ChatGPT国内中文版镜像网站整理合集(2024/11/01)
  • 快速入门:Visual Studio 中的 Docker
  • HTMLCSS:旋转的动态卡片
  • LInux系统编程(二)操作系统和进程
  • 锁策略, cas 和 synchronized 优化过程
  • Python爬虫详解:原理、常用库与实战案例
  • 【刷题13】链表专题
  • 使用WebAssembly优化Web应用性能
  • nodejs入门教程20:nodejs文件系统
  • uniapp-vue3比对筛选
  • 软件测试基础三(前端知识)
  • Elastix-基于ITK的医学图像配准库
  • Java中对象的转移(1)——序列化与反序列化
  • 初探Flink的序列化
  • 手撕快排的三种方法:让面试官对你刮目相看
  • 到底要不要用SAP Screen Personas
  • Unity中的屏幕坐标系
  • Matlab车牌识别课程设计报告模板(附源代码)
  • 【OJ题解】C++实现反转字符串中的每个单词
  • Excel函数CUnique连接合并指定区域的唯一值
  • 远程控制时频繁掉线的原因
  • [每周一更]-(第121期):模拟面试|微服务架构面试思路解析