约瑟夫环问题
Posted 下周LGD该赢了吧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了约瑟夫环问题相关的知识,希望对你有一定的参考价值。
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知m个人(以编号1,2,3...m分别表示)围坐在一张圆桌周围。
从编号为1的人开始报数,数到k的那个人出列;他的下一个人又从1开始报数,数到k的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。求每次出列的人的编号。
参考:http://www.cnblogs.com/yangyh/archive/2011/10/30/2229517.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 #include <bits/stdc++.h> 2 using namespace std; 3 void f(int m, int k, int i) 4 { 5 if(i == 1) return (m+k-1)%m; 6 else return (f(m-1, k, i-1) + k)%m; 7 } 8 int main() 9 { 10 return 0; 11 }
递推写法:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int k, m; 6 cin>>k>>m; 7 int x = 0; 8 for(int i = 2; i <= m; i++) 9 { 10 x = (x+k)%i; 11 } 12 cout<<x+1<<endl; 13 return 0; 14 }
以上是关于约瑟夫环问题的主要内容,如果未能解决你的问题,请参考以下文章