• 约瑟夫问题(一)


    约瑟夫问题(一) --Josephus Problem

          这是17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。

    问题分析与算法设计:

         约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多。这里给出一种实现方法。 题目中30个人围成一圈,因而启发我们用一个循环的链来表示。可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。

    #include<iostream>
    #include<stdlib.h>
    using namespace std;
    void make(int *base,int n,int pos,int c,int m)
    //参数的意义。base数组名,n数组长度。pos跑格的一个东西。c计算次数的。m每次跑路的长度。
    {
    int j=0;
    cout<<"NO. "<<++c<<""<<pos+1<<"位出列"<<endl;//输出
    base[pos]=0;//踢掉
    if(c==n)return; //出口
    while(j-m)if(base[pos=(pos+1)%n])j++;//递归点 ,每次数到几这个3就改到几
    make(base,n,pos,c,m);//递归
    }
    int main()
    {
    int n,m,c=0,pos;//从N开始数,则把pos改为N-1就行了.
    cout<<"请输入总人数"<<endl;
    cin>>n;
    cout<<"请输入要隔几个人:"<<endl;
    cin>>m;
    int *base=new int[n];
    for(int i=0;i<n;i++)base[i]=1;
    pos=m-1;
    make(base,n,pos,c,m);
    delete[]base;
    system("PAUSE");
    return 0;
    }

    root@bt:~# g++ -o JosephusProblem.out JosephusProblem.cpp
    root@bt:~# ./JosephusProblem.out
    请输入总人数
    30
    请输入要隔几个人:
    9
    NO. 1 第9位出列
    NO. 2 第18位出列
    NO. 3 第27位出列
    NO. 4 第6位出列
    NO. 5 第16位出列
    NO. 6 第26位出列
    NO. 7 第7位出列
    NO. 8 第19位出列
    NO. 9 第30位出列
    NO. 10 第12位出列
    NO. 11 第24位出列
    NO. 12 第8位出列
    NO. 13 第22位出列
    NO. 14 第5位出列
    NO. 15 第23位出列
    NO. 16 第11位出列
    NO. 17 第29位出列
    NO. 18 第17位出列
    NO. 19 第10位出列
    NO. 20 第2位出列
    NO. 21 第28位出列
    NO. 22 第25位出列
    NO. 23 第1位出列
    NO. 24 第4位出列
    NO. 25 第15位出列
    NO. 26 第13位出列
    NO. 27 第14位出列
    NO. 28 第3位出列
    NO. 29 第20位出列
    NO. 30 第21位出列
    sh: PAUSE: command not found
    root@bt: ~#
    ************************************************* 

    现在的衍生问题
          就是说有n个人围成一圈,然后说从任意指定的一个 人那里为起点,以m个人为单位,每转m个人第m个人被杀死。当起始人也就是所谓的 第1个人是最后被杀死的,这个m就是为所求,满足这样就叫joseph问题。

    *************************************************

    更新ubuntu软件源:

    root@bt: ~# cat /etc/apt/sources.list

    deb http://all.repository.backtrack-linux.org revolution main microverse non-free testing

    deb http://32.repository.backtrack-linux.org revolution main microverse non-free testing

    deb http://source.repository.backtrack-linux.org revolution main microverse non-free testing

    添加密钥:

    root@bt: gpg —keyserver subkeys.pgp.net —recv 475A6B7F

    root@bt: sudo gpg —keyserver subkeys.pgp.net —recv 475A6B7F

    root@bt: gpg --keyserver subkeys.pgp.net --recv 475A6B7F

    完整安装vim和rpm(vim编辑器高亮):

    root@bt: sudo apt-get install vim

    root@bt: sudo apt-get install rpm

    参考:

       http://caterpillar.onlyfun.net/Gossip/AlgorithmGossip/JosephusProblem.htm



  • 相关阅读:
    怎样练习一万小时
    新闻的未来
    有些人无缘再见,却一生想念
    媒体该如何展示事实之美?
    传统媒体:广告都去哪儿了?
    一线从业者干货分享:不做“忧伤”的媒体人
    整理者与信息平台
    把媒体当手段还是当目的?
    媒体人转身,转身去哪里?
    腾讯新闻的海量服务
  • 原文地址:https://www.cnblogs.com/Gemgin/p/2365516.html
Copyright © 2020-2023  润新知