关于约瑟夫问题(Josephus Problem)
来源:互联网 发布:可汗学院 黑板软件 编辑:程序博客网 时间:2024/06/04 17:50
这个问题是以弗拉维奥·约瑟夫斯命名的,他是1世纪的一名犹太历史学家。他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以报数的方式决定谁杀掉谁。约瑟夫斯说服了一个人,他们将向罗马军队投降,不再自杀。约瑟夫希望知道他们两个人应该怎样坐才能保证两个最终活下来。
换句话说,也就是n个人坐成一个环,从第一个人从1开始报数,报到m的人出局,然后从下一个人开始继续从1开始报数……当
图片来源:http://blog.csdn.net/jtlyuan/article/details/7433693
为了取模方便,我们不再从1开始给人标号,我们从0开始顺时针标号。
每次有人出局后,所有人将被重新标号,出局者的下一个人将被标上0,其他人将被依次标上号。
我们考虑一个对应关系
先给出结论:
我原来想证明这个式子,但是想了一会儿发现这个式子不应该是拿来证明的,可以很好地理解它。A在这一轮的标号是
那么对于约瑟夫问题,我们可以知道,当剩下两个人的时候,一个人的编号是0,另一个编号是1。那么通过
部分代码如下:
int t[2];t[0]=0;t[1]=1;for (int i=3;i<=n;i++){ for(int j=0;j<=1;j++){ t[j]=(t[j]+m)%i; }}
我们换一个问题:如果我们要计算所有人的出局顺序呢?也就是按出局顺序依次给出出局者的初始标号。比如第一张图中的结果就是3,6,9,12,15,18……
一个一个数的复杂度为
我们对人数建一颗线段树,每个节点
我们先讨论一下n=9,m=4的情况,下图是初始局面:
我们定义一个
刚开始
如果
我们去寻找点(总是先找左节点),当找到
进入下一层查找,发现
我们继续进入下一层节点寻找,发现
之后的局面如下:
下一个出局的人应该是第
如果
为什么要
之后的局面如下:
下一个出局的人是第3个人,也就是3号,再下一个是第6个人,9号。
代码如下:该代码在CODEVS_1282提交通过
#include<bits/stdc++.h>using namespace std;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int t[150000];int n,m;void build(int index,int l,int r){ if (l==r){t[index]=1;return;} int mid=(l+r)>>1; build(index<<1,l,mid); build(index<<1|1,mid+1,r); t[index]=t[index<<1]+t[index<<1|1];}int read(int index,int l,int r,int aim){ if (l==r) { t[index]=0; return l; } int mid=(l+r)>>1; t[index]--; if (t[index<<1]>=aim) return read(index<<1,l,mid,aim); else return read(index<<1|1,mid+1,r,aim-t[index<<1]);}int main(){ n=read();m=read(); build(1,1,n); int aim=1; for (int i=1;i<=n;i++){ aim=(aim+m-1)%t[1]; if(aim==0) aim=t[1]; printf("%d%c",read(1,1,n,aim)," \n"[i==n]); } return 0;}
- 关于约瑟夫问题(Josephus Problem)
- 约瑟夫问题(Josephus problem)
- 约瑟夫问题(Josephus Problem)
- 约瑟夫问题(Josephus problem)
- 约瑟夫问题(Josephus problem)
- Josephus problem(约瑟夫问题)
- 约瑟夫问题Josephus problem
- 约瑟夫环问题(josephus problem)详解
- Algorithm Gossip: 约瑟夫问题(Josephus Problem)
- 约瑟夫(Josephus problem)环问题初探
- Java-约瑟夫问题(Josephus Problem)
- 约瑟夫(Josephus)问题
- 约瑟夫(Josephus)问题
- 约瑟夫(Josephus)问题
- 约瑟夫问题(Josephus problem)1:出列的序列
- 约瑟夫问题(Josephus problem)2:某人何时出列
- 约瑟夫问题(Josephus Problem)3:谁最后一个出列
- 约瑟夫问题(Josephus Problem)算法分析及代码
- SimpleUrlHandlerMapping使用
- redis jedis
- linux命令 --vim
- iOS方向盘代码
- [LeetCode]55. Jump Game
- 关于约瑟夫问题(Josephus Problem)
- 剑指offer:链表中环的入口结点
- 安卓按键读取txt开头出现未知字符的问题
- Codeforces Round #433 (Div. 1) B Jury Meeting(思维)
- 文章标题
- [中等] UVa OJ 11400 Lighting system design 动态规划
- HTML1.1
- C语言--位运算
- mybatis $ 和# 的区别