约瑟夫问题(一)

约瑟夫问题(一) --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/archive/2012/02/23/2365516.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值