约瑟夫环问题
2016-03-13 11:27
246 查看
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知m个人(以编号1,2,3...m分别表示)围坐在一张圆桌周围。
从编号为1的人开始报数,数到k的那个人出列;他的下一个人又从1开始报数,数到k的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。求每次出列的人的编号。
参考:/article/6449568.html
假设m = 10 k = 3 排列按编号从0开始
0 1 2 3 4 5 6 7 8 9
那么第一个出列的是2。
这时候从3开始数,那么序列变成了 3 4 5 6 7 8 9 0 1
可以发现如果序列0 1 2 3 4 5 6 7 8 (每个位置的数+3)%10,就变成了3 4 5 6 7 8 9 0 1
所以可以设f[m][k][i]表示当前长度为m,第i次出环的编号。
那么当i = 1的时候结果为 (m + k - 1)%m。
当i != 1的时候,结果为(f[m-1][k][i-1] + k )%m。
如果题目编号要求从1开始,那么最终结果为f[m][k][i]+1。
递推写法:
从编号为1的人开始报数,数到k的那个人出列;他的下一个人又从1开始报数,数到k的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。求每次出列的人的编号。
参考:/article/6449568.html
假设m = 10 k = 3 排列按编号从0开始
0 1 2 3 4 5 6 7 8 9
那么第一个出列的是2。
这时候从3开始数,那么序列变成了 3 4 5 6 7 8 9 0 1
可以发现如果序列0 1 2 3 4 5 6 7 8 (每个位置的数+3)%10,就变成了3 4 5 6 7 8 9 0 1
所以可以设f[m][k][i]表示当前长度为m,第i次出环的编号。
那么当i = 1的时候结果为 (m + k - 1)%m。
当i != 1的时候,结果为(f[m-1][k][i-1] + k )%m。
如果题目编号要求从1开始,那么最终结果为f[m][k][i]+1。
#include <bits/stdc++.h> using namespace std; void f(int m, int k, int i) { if(i == 1) return (m+k-1)%m; else return (f(m-1, k, i-1) + k)%m; } int main() { return 0; }
递推写法:
#include <bits/stdc++.h> using namespace std; int main() { int k, m; cin>>k>>m; int x = 0; for(int i = 2; i <= m; i++) { x = (x+k)%i; } cout<<x+1<<endl; return 0; }
相关文章推荐
- MySQL存储引擎 MyISAM与InnoDB区别
- ios-基础之【8】-NSDictionary
- Codeforces Round #345 (Div. 2) A. Joysticks
- NYOJ 序列置换
- 剑指offer 顺时针打印矩阵
- makefile
- 双向链表中的交换节点
- Android性能测试工具 之Emmagee
- “进度条”博客——第二周
- 在windows导入mysql的示例employees数据库
- Servlet学习笔记
- Linux下gcc编译器的使用
- 第三周项目4:穷举法解决组合问题
- 编写你自己的单点登录(SSO)服务
- Nginx优化具体,应对高并发
- JavaScrict中的断言调试
- 3.12课·········数组
- js添加var和不加var区别
- RIGHT-BICEP单元测试——“二柱子四则运算升级版”
- 毛玻璃效果