谁能笑到最后,约瑟夫环-Josephus问题求解
一、 简述Josephus问题
N个人站成一环,从1号开始,用刀将环中后面一个人“消灭“”掉,之后再将刀递给下一个人,这样依次处理,最后留下一个幸存者。
二、 求解方法
1. 约瑟夫问题如果使用链表来求解比较麻烦,这里采用循环队列的处理。
约瑟夫问题可以等价为l连续地DeQueue()两次,然后再将第一次DeQueue()的值EnQueue()入队列尾,直到队列中只剩下一个元素。
# 循环队列代码如下:
#include <stdio.h>
#include <stdlib.h> #define MAX 100 /* Maximum size of Queue */ typedef struct _Queue *Queue;
struct _Queue {
int A[MAX];
int Head, Tail;
int Num_of_Items;
}; /* Queue struct and pointer define */ void EnQueue( Queue Q, int x )
{
if ( Q->Num_of_Items < MAX ) {
/* Cycle Queue not full */
if ( Q->Num_of_Items == ) {
Q->Head = Q->Tail = ;
Q->A[] = x;
} else {
Q->Tail = (Q->Tail + ) % MAX; /* Tail insert */
Q->A[Q->Tail] = x;
}
Q->Num_of_Items++;
} else {
printf("Warning: Full Queue!\n");
return;
}
} int DeQueue( Queue Q )
{
if ( Q->Num_of_Items < ) {
/* empty queue */
printf("Warning: Empty Queue!\n");
} else {
int ret = Q->A[Q->Head];
Q->Num_of_Items--;
Q->Head = (Q->Head + ) % MAX;
return ret;
}
}
# 循环队列解约瑟夫问题:
void JosephusByQueue()
{
_Queue Que;
Queue Q = &Que; /* initial */
//Queue Q = (Queue)malloc( sizeof(struct _Queue) );
Q->Num_of_Items = ; int i, j, n, answer;
printf("Enter an integer (1--99):");
scanf("%d", &n); /* Solve Josephus Problem */
/* Step 1: Put all the number between 1 to n to the Queue */
for ( i = ; i <= n; i++ ) {
EnQueue( Q, i);
} /* Step 2: Start killing for n-1 rounds */
for ( i = ; i < n; i++ ) {
j = DeQueue( Q ); /* first dequeue item */
DeQueue( Q );
EnQueue( Q, j );
} answer = Q->A[Q->Head]; /* the last item */
printf("The value of J(%d) is: %d\n", n, answer);
}
2. 每次隔一个人就消灭掉一人,经过一圈,消灭一半,就等于累次除二。等价于二的幂相关问题。
对于Josephus( N ):
[1] 若N为二次幂(N = 2^M),M为幂次。从开始一圈消除偶数,再消除奇数,每次跳过起始的1,最终留下1。
EX 1: J( 8 ): Green : start , Red: delete
2 3 4 5 6 7 8 --> 1 2 3 4 5 6 7 8 --> 1 3 5 7
--> 1 3 5 7 --> 5 --> 1 5 --> 1
[2] 若N为奇数,可化为(N = 2^M + K),先 消除K个人,即经历过2K个人后。又为偶数问题,留下的[ Last=2K+1 ]。
EX 2: J( 10 ) : N = 10, M = 3, K = 2 --> J( 10 ) = 2*k + 1 = 5
公式: N = 2^M + K , K= N - 2^M。 J( N ) = 2 *( N - 2^M ) + 1
求解代码:
/* 数学解法:N = 2^M + K | Last = 2 *( N - 2^M ) + 1 */
void Josephus()
{
int i, n, m_prime, k;
printf("Enter an integer:");
scanf("%d", &n); i = ;
while ( i < n ) {
/* find the largest power of 2 that less than n */
i *= ;
}
m_power = i / ;
k = n - m_power;
printf("The remain one is %d!\n", ( * k + ));
}
主函数:
int main(int argc, char *argv[])
{
printf("Method 1: Math solving\n");
Josephus(); printf("\nMethod 2: Queue solving\n");
return ;
}
参考资料:
[1] 中国大学MOOC-数据结构-台湾清华大学-04BasicDataStructure
[2] 2的幂在约瑟夫环问题的应用https://www.cnblogs.com/sirlipeng/p/5387830.html#undefined
图片来自网络
谁能笑到最后,约瑟夫环-Josephus问题求解的更多相关文章
- 单向环形链表解决约瑟夫环(Josephus)问题
一.约瑟夫环问题 Josephu 问题为:设编号为1,2,- n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那 ...
- 习题3.10 约瑟夫环 josephus问题
/* assume a header */ /* 双向循环链表 */ struct Node; typedef struct Node * PtrToNode; typedef PtrToNode L ...
- 约瑟夫环问题(Josephus)
约瑟夫环:用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至最后一个元素并输出该元素的值. 一.循环链表:建立一个有N个元素的循环链表,然后从链表头开始遍历并记数,如果计数值为M,则 ...
- LightOJ - 1179 Josephus Problem(约瑟夫环)
题目链接:https://vjudge.net/contest/28079#problem/G 题目大意:约瑟夫环问题,给你n和k(分别代表总人数和每次要数到k),求最后一个人的位置. 解题思路:因为 ...
- 组合数学--约瑟夫环问题 Josephus
约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环. 有n个囚犯站成一个圆圈,准备处决.首先从一个人开始,越过k-2个人(因为第 ...
- Josephus环的四种解法(约瑟夫环)
约瑟夫环 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个 ...
- 约瑟夫环的java解决
总共3中解决方法,1.数学推导,2.使用ArrayList递归解决,3.使用首位相连的LinkedList解决 import java.util.ArrayList; /** * 约瑟夫环问题 * 需 ...
- 简洁之美 -约瑟夫环的python 解法
问题描述: 约瑟夫环问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到k的那个人出列:他的下一个人又从1开始报数,数到k的那个人又出列:依此规律重复下 ...
- 约瑟夫环 --- 面向对象 --- java代码
约瑟夫环 的 面向对象 解法 罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个 ...
随机推荐
- 【转】winrar命令行详解
从命令行也可以运行 WinRAR 命令,常规的命令行语法描述如下: WinRAR <命令> -<开关1> -<开关N> <压缩文件> <文件.. ...
- nginx导致的session丢失的解决方法
nginx把同一用户的请求分发到了不同的服务器,如果不做处理,就会导致session丢失. 1.粘性IP: 在nginx配置文件中,增加配置, 对IP进行HASH后,散列到服务器. 这个实现最简单.但 ...
- 浅谈SAP Cloud for Sales 自动化
在Jerry还在本科进行计算机理论知识学习时,我曾经把软件开发里的质量工程师(Quality Engineer)理解成是每天只是简单地做着运行开发人员编写好的软件,如果发现问题,通知开发人员去修改这种 ...
- Android进阶笔记14:3种JSON解析工具(org.json、fastjson、gson)
一. 目前解析json有三种工具:org.json(Java常用的解析),fastjson(阿里巴巴工程师开发的),Gson(Google官网出的),其中解析速度最快的是Gson. 3种json工具下 ...
- 【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信
http://blog.csdn.net/xiaominghimi/article/details/51586492 一用到跨平台的引擎必然要有引擎与各平台原生进行交互通信的需要.那么Himi先讲解R ...
- Linux.开关机&登出&用户管理
关机重启: shutdown: shutdown –h now 立该进行关机 shudown -h 1 "hello, 1 分钟后会关机了" ...
- fastjson是什么东东?
fastjson是一个Java语言编写的高性能功能完善的JSON库.它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库.Fastjson ...
- 简单说一说对JavaScript原型链的理解
每一个JavaScript对象都和另一个对象相关联,相关联的这个对象就是我们所说的“原型”.每一个对象都会从原型继承属性和方法.有一个特殊的对象没有原型,就是Object,还有一种通过Object.c ...
- ASP.NET Core MVC的路由参数中:exists后缀有什么作用,顺便谈谈路由匹配机制
我们在ASP.NET Core MVC中如果要启用Area功能,那么会看到在Startup类的Configure方法中是这么定义Area的路由的: app.UseMvc(routes => { ...
- Hadoop 学习之——HDFS
HDFS是HADOOP中的核心技术之一——分布式文件存储系统.Hadoop的作者Doug Cutting 和Mike 是根据Google发布关于GFS 的研究报告所设计出的分布式文件存储系统. 一.H ...