博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
约瑟夫环问题
阅读量:5789 次
发布时间:2019-06-18

本文共 4082 字,大约阅读时间需要 13 分钟。

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。

数组方式

假设下标从0开始,0,1,2 .. m-1共m个人,从1开始报数,报到k则此人从环出退出,问最后剩下的一个人的编号是多少?

现在假设m=10

0 1 2 3 4 5 6 7 8 9 k=3
第一个人出列后的序列为:
0 1 3 4 5 6 7 8 9
即:
3 4 5 6 7 8 9 0 1(*)
我们把该式转化为:
0 1 2 3 4 5 6 7 8 (**)
则你会发现: ((**)+3)%10则转化为(*)式了

也就是说,我们求出9个人中第9次出环的编号,最后进行上面的转换就能得到10个人第10次出环的编号了

设f(m,k,i)为m个人的环,报数为k,第i个人出环的编号,则f(10,3,10)是我们要的结果
当i=1时, f(m, k ,i) = (m+k-1) % m
当i!=1时, f(m, k, i)= ( f(m-1, k, i-1)+k ) % m

Java实现:

public class Test {    public static void main(String[] args) {        for (int i = 1; i <= 10; i++){            System.out.print(fun(10,3,i) + " ");        }    }    public static int fun(int m, int k, int i){        if (i == 1){            return (m + k - 1) % m;        }else{            return (fun(m - 1, k, i - 1) + k) % m;        }    }}

上述实现将结点的值设为0~n-1,若要变为1~n-1,则打印fun(m, k, i) + 1即可。

Python实现:

def fun(m, k, i):    if i == 1:        return (m + k - 1) % m    else:        return (fun(m - 1, k, i - 1) + k) % mfor i in range(1, 11):    print(fun(10, 3, i), end=' ')

C++实现:

#include 
using namespace std;int fun(int m, int k, int i);int main(){ for (int i = 1; i <= 10; i++) { cout<

链表方式

使用一个循环链表来实现,每次将一个结点移出链表。

Java实现:

class ListNode{    int val;    ListNode next;    ListNode(int x) {val = x;}}public class Josephus {    ListNode head;    int n;    Josephus(int x){        n = x;        head = new ListNode(1);        ListNode pre = head;        ListNode cur = null;        for (int i = 2; i <= n; i++){            cur = new ListNode(i);            pre.next = cur;            pre = cur;        }        cur.next = head;    }    public void PerformKilling(int d){        d = d % n;        ListNode pre = null;        ListNode cur = head;        int count = 1;        while (count++ <= n){ // while (cur.next != cur)            int i = 1;            while (i++ < d){                pre = cur;                cur = cur.next;            }            System.out.println("Killing: " + cur.val);            pre.next = cur.next;            cur = cur.next;            i = 1;        }        //System.out.println("Killing: " + cur.val);    }}

Python实现:

class ListNode:    def __init__(self, x):        self.val = x        self.next = Noneclass Josephus:    def __init__(self, x):        self.n = x        self.head = ListNode(1)        pre = self.head        for i in range(2, x + 1):            cur = ListNode(i)            pre.next = cur            pre = cur        cur.next = self.head    def performKilling(self, d):        cur = self.head        while cur.next != cur:            for i in range(1, d):                pre = cur                cur = cur.next            print(cur.val, end=' ')            pre.next = cur.next            cur = cur.next        print(cur.val, end=' ')J = Josephus(10)J.performKilling(3)

C++实现:

#include 
using namespace std;struct ListNode{ int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {}};class Josephus{public: Josephus(int x) { n = x; head = new ListNode(1); ListNode *pre = head; ListNode *cur; for (int i = 2; i <= x; i++) { cur = new ListNode(i); pre->next = cur; pre = cur; } cur->next = head; } void performKilling(int d) { d %= n; int count = 1; ListNode *pre; ListNode *cur = head; while (count++ <= n) //while (cur->next != cur) { for (int i = 1; i < d; i++) { pre = cur; cur = cur->next; } cout<
val<<" "; pre->next = cur->next; delete cur; cur = pre->next; } //cout<
val; //delete cur; }private: ListNode *head; int n; //size of the linked list};int main(){ Josephus *J = new Josephus(10); J->performKilling(3);}

(使用C++时,特别注意的是释放内存

结束条件可以设置为已经打印了n个结点,或者链表中仅有一个结点(继续打印该唯一结点)。

转载地址:http://jgqyx.baihongyu.com/

你可能感兴趣的文章
java springcloud版b2b2c社交电商spring cloud分布式微服务(十五)Springboot整合RabbitMQ...
查看>>
SpringCloud使用Prometheus监控(基于Eureka)
查看>>
10g手动创建数据库
查看>>
Linux—文件系统
查看>>
运用Loadrunner测试Mysql数据库性能
查看>>
Spring MVC EL表达式不能显示
查看>>
Tomcat version 5.5 only supports J2EE 1.2, 1.3, and 1.4 Web modules
查看>>
【致青春】我们挥霍时间的年代
查看>>
WDS系列之四:自定义安装映像
查看>>
CentOS7 NTP server + keepalived
查看>>
jQuery 表单应用:全选/取消全选,表单验证,网页选项卡切换
查看>>
分布式计算相关
查看>>
Castle 整合.NET Remoting
查看>>
Windwos Server 2008 R2 DHCP服务
查看>>
SAS和SATA硬盘的区别
查看>>
现代程序设计 学生情况调查
查看>>
U盘安装linux后无法引导
查看>>
C# 矩阵作业
查看>>
俺的新书《Sencha Touch实战》终于出版了
查看>>
《空中交通管理基础》-潘卫军主编-第三章-航空器和飞行高度层
查看>>