51nod 1073约瑟夫环 递归公式法
约瑟夫环问题的原来描述为,设有编号为1,2,……,n的n(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,……,如此下去,直到所有人全部出圈为止。当任意给定n和m后,设计算法求n个人出圈的次序。 稍微简化一下。
问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。
利用数学推导,如果能得出一个通式,就可以利用递归、循环等手段解决。下面给出推导的过程:
(1)第一个被删除的数为 (m - 1) % n。
(2)假设第二轮的开始数字为k,那么这n - 1个数构成的约瑟夫环为k, k + 1, k + 2, k +3, .....,k - 3, k - 2。做一个简单的映射。
k -----> 0
k+1 ------> 1
k+2 ------> 2
...
...
k-2 ------> n-2
这是一个n -1个人的问题,如果能从n - 1个人问题的解推出 n 个人问题的解,从而得到一个递推公式,那么问题就解决了。假如我们已经知道了n -1个人时,最后胜利者的编号为x,利用映射关系逆推,就可以得出n个人时,胜利者的编号为 (x + k) % n。其中k等于m % n。代入(x + k) % n <=> (x + (m % n))%n <=> (x%n + (m%n)%n)%n <=> (x%n+m%n)%n <=> (x+m)%n
(3)第二个被删除的数为(m - 1) % (n - 1)。
(4)假设第三轮的开始数字为o,那么这n - 2个数构成的约瑟夫环为o, o + 1, o + 2,......o - 3, o - 2.。继续做映射。
o -----> 0
o+1 ------> 1
o+2 ------> 2
...
...
o-2 ------> n-3
这是一个n - 2个人的问题。假设最后的胜利者为y,那么n -1个人时,胜利者为 (y + o) % (n -1 ),其中o等于m % (n -1 )。代入可得 (y+m) % (n-1)
要得到n - 1个人问题的解,只需得到n - 2个人问题的解,倒推下去。只有一个人时,胜利者就是编号0。下面给出递推式:
f [1] = 0;
f [ i ] = ( f [i -1] + m) % i; (i>1)
有了递推公式,实现就非常简单了,给出循环的两种实现方式。再次表明用标准库的便捷性。
对于上面第一个映射表,由映射关系可得,如果0~n-1中某人报了m-1,设这个人为x,那么原位置一定是(x+k)%n
相信大家都能看出规律,为什么要%n,因为后面的序号不会一直无限制增大,会变小,比如4,5,6,7,1,2,那么1和2就是(4+4)%7,(4+5)%7
附上代码,当然这题也可以递归推一推,但没有必要
#include <stdio.h> using namespace std;
const int maxn=1e6+7;
int f[maxn];
int main(){
int n,k;
scanf("%d%d",&n,&k);
f[1]=0;
for(int i=2;i<=n;++i){
f[i]=(f[i-1]+k)%i;
}
printf("%d",f[n]+1);
return 0;
}
51nod 1073约瑟夫环 递归公式法的更多相关文章
- 51nod 1074 约瑟夫环 V2
N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数.问最后剩下的人的编号. 例如:N = 3,K = 2.2号先出列,然后是1号,最后剩下的是3号. ...
- [剑指Offer]62-圆圈中最后剩下的数(约瑟夫环问题)(法二待做)
题目链接 https://www.nowcoder.com/practice/f78a359491e64a50bce2d89cff857eb6?tpId=13&tqId=11199&t ...
- 关于递推算法求解约瑟夫环问题P(n,m,k,s)
一. 问题描述 已知n个人,分别以编号1,2,3,...,n表示,围坐在一张圆桌周围.从编号为k的人开始报数1,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去, ...
- 约瑟夫环问题详解(java版)
1 什么是约瑟夫环问题? 约瑟夫,是一个古犹太人,曾经在一次罗马叛乱中担任将军,后来战败,他和朋友及另外39个人躲在一口井里,但还是被发现了.罗马人表示只要投降就不死,约瑟夫想投降,可是其他人坚决不同 ...
- 【约瑟夫环变形】UVa 1394 - And Then There Was One
首先看到这题脑子里立刻跳出链表..后来继续看如家的分析说,链表法时间复杂度为O(n*k),肯定会TLE,自己才意识到果然自个儿又头脑简单了 T^T. 看如家的分析没怎么看懂,后来发现这篇自己理解起来更 ...
- C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解
剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...
- 小小c#算法题 - 12 - Joseph Circle(约瑟夫环)
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数(从1开始报数),数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又 ...
- 17965 幸运之星(优先做) 约瑟夫环问题O(n)
17965 幸运之星(优先做) 时间限制:100MS 内存限制:65535K 提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC;VC Description 每年新年派对的最后 ...
- javascript中使用循环链表实现约瑟夫环问题
1.问题 传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围.犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案.他们围成一个圈,从一个人开始,数到第 ...
随机推荐
- SVM 支持向量机算法-实战篇
公号:码农充电站pro 主页:https://codeshellme.github.io 上一篇介绍了 SVM 的原理和一些基本概念,本篇来介绍如何用 SVM 处理实际问题. 1,SVM 的实现 SV ...
- Java基础复习4
选择排序(擂台排序): public class demo1 { public static void main(String[] args) { // TODO Auto- ...
- java之 Request
0x01.Request 什么是request 在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息. ...
- SSL_ERROR_WANT_READ
``` 47757 2020/05/07 06:36:04 [debug] 19413#19413: *23421 event timer: 11, old: 15581551413, new: 15 ...
- 在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态.这些都是计算属性无法做到的.
- Webpack4.0各个击破(7)plugin篇
目录 一. plugin概述 1.1 Plugin的作用 1.2 Compiler 1.3 Compilation 二. 如何写一个plugin 四. 实战 [参考] 一. plugin概述 1.1 ...
- Language Guide (proto3) | proto3 语言指南(七)更新消息类型
Updating A Message Type - 更新消息类型 如果现有的消息类型不再满足您的所有需要(例如,您希望消息格式有一个额外的字段),但是您仍然希望使用用旧格式创建的代码,不要担心!在不破 ...
- centos设系统置语言为中文
[root@host /]# vim /etc/sysconfig/i18n #i18n 是 internationalization 的缩写形式,意即在 i 和 n 之间有 18 个字母,本意是指软 ...
- 在线安装mysql
http://www.cnblogs.com/wishwzp/p/7113403.html
- 设计模式(十四)——模板模式(SpringIOC源码分析)
1 豆浆制作问题 编写制作豆浆的程序,说明如下: 1) 制作豆浆的流程 选材--->添加配料--->浸泡--->放到豆浆机打碎 2) 通过添加不同的配料,可以制作出不同口味的豆浆 3 ...