The Josephus can be solved with the following algorithm:
int josephus(int n, int k) { if (n == 1) return 1; else return (josephus(n - 1, k) + k-1) % n + 1; }
However, I would also like to know who was the i-th person killed in the game. For example, with n=10, k=2, the 1st person to get killed is the 2nd. How can I get this answer? Is there anyway I can find it using the algorithm above?
An O(m*lg(km)) algorithm
npeople in a ring, numbered from0ton-1clockwise. Start from person with number0, everym-th is executed, the following program give number of thek-th killed person.kstart from0.Explanation
I use
//to denotefloor divison.let's say everyone will additionally count off from
0, who reportsm-1is the0-th killed person. who reports2m-1is the1-th killed person and so on.Say somebody reports
i. His last reports isj. When he reportsj, there arej//mdead,n-(j//m)alive.So
i = (n - (j//m)) + j->j-j//m = i-nSuppose
j = am + b; 0<=b<m-1; a,b is int, notice hereb!=m-1because he won't die.Then
a(m-1) + b = (i-n). Using bezout's lemma and extended euclidean algorithm, we gota=-c; b=(i-n)+c*(m-1); with any int c. Andbhas only one solution in interval[0,m-1). Sob = ((i-n)+c*(m-1)) %(m-1), which equals to(i-n)%(m-1). After that, you can calculatej=(i-n) + (i-n)//(m-1) = (m*(i-n))//(m-1).By this recurrence relation, you can calculate any
k-th killed person.Time complexity
O(m*lg(mk)).An O(n*lg(n)) simulation algorithm
If
mis pretty large, you can use some Balance Tree to implement an O(n*lg(n)) algorithm.