约瑟夫环问题

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知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 }
原文地址:https://www.cnblogs.com/titicia/p/5271498.html