**(1) O (n) Time Solution**

**Only the last person out of the game can be solved, that is, the last person left behind. By default, the number starts from 1.**

N people eat at a round table, and each M person kills one until the last one is left.

Who are the last to be asked?

Mark the person as 0, 1, 2,..., n-1, respectively, to obtain a completely residual system of N.

The following recursive formula is available:

/-(J (n-1, m) + m + 1) mod N, when n> 1

J (n, m) = |, n, m, Z

/-0, when n = 1

Today's Data Structure class is talking about the linked list simulation solution for this thing. I started thinking about number theory solutions.

I have been confused about this problem for a long time. Today I finally thought of using the recursive method taught by Li changyong.

The following is a proof found on the Internet:

This is Joseph's problem.

Set n people to a circle with the number 0 .. n-1. The number of loop reports from 1 to k starts from the first person. When the number is reported to K, the person goes out of the circle. Set J (n, k, I) to the ID of the person whose th ring is outbound.

Theorem 1:

J (n, k, 1) = (k-1) mod N, (n> = 1, k> = 1 )............ (1)

Proof:

Evidence can be obtained directly by definition. Q. e.d.

Theorem 2:

J (n + 1, K, I + 1) = (k + J (n, k, I) mod (n + 1), (N> = 1, k> = 1, 1 <= I <= N )............ (2)

Proof:

Set J (n, k, I) to G. Therefore, if n people start from 0, the I-th outbound labeling is G. Now consider J (n + 1, K, I + 1), because J (n + 1, k, 1) = (k-1) mod (n + 1 ), that is, the first step is to delete the number (k-1) mod (n + 1), and the second step is to start from the number K. So the problem becomes to find the I-th number that is deleted from K in the remaining n numbers (note this (k-1) mod (n + 1) deleted), which happens to be (G + k) mod (n + 1) and (2. Q. e.d.

According to (2), it is easy to obtain the number of I outbound loops in N numbers.

For k = 2, 3, you can directly export the formula. However, the formula for k> = 4 has not yet been deduced. Currently, the best algorithm is a fast algorithm based on the estimation of the upper and lower bounds of J (n, k, I.

For more detailed analysis, see

[1] Lorenz halbeisen, the Joseph problem, 1994

[2] Woodhouse, D., the extended Joseph PHUs problem, rev. Mat. hisp.-Amer. (4) 33 (1973), 207-218

[3] Robinson, W. J., The Joseph problem, math. gazet44 (1960), 47-52

[4] jakobczyk, F., on the generalized Joseph PHUs problem, Glasgow math. J.14 (1973), 168-173

And a program:

// The function receives N and M (N people eat at a round table, and each M person kills one), and returns the first persons in the circle.

/* E.g. yuesefu (5, 2) = 3

Yuesefu (2,100) = 1 */

Int yuesefu (int n, int m) // The default value starts from the number of persons numbered 1.

{

Int I, r = 0;

For (I = 2; I <= N; I ++) r = (R + M) % I;

Return R + 1;

}

**Summary:**The time complexity of this algorithm is O (n), which has greatly improved compared with the simulation algorithm. N, m equals 1 million,

10 million is not a problem. It can be seen that the appropriate use of mathematical strategies not only makes programming simple, but also

This will multiply the algorithm execution efficiency.

Or see: http://blog.csdn.net/lvroyce/archive/2009/02/13/3883760.aspx

**(2) General Solution**

# Include <iostream>

Using namespace STD;

// N indicates the number of people (number 1, 2 ,......, X), M indicates the column number, and K indicates the start person number.

Void Joseph FUS (int n, int M, int K, int A [])

{

Int J = 0, L = 0;

While (L <= N)

{

For (INT I = 1; I <= N; I ++)

{

If (A [I] = 1)

{

J ++;

If (j = m)

{// Meet the column number

A [I] = 0;

If (I = N & K> 1)

{

Cout <1 <Endl;

}

Else

{

Cout <I + (k-1) <Endl;

}

J = 0;

L ++;

}

}

}

}

}

Int main ()

{

Int n, m, K;

Cout <"Enter the parameter: n -- total number of people, m -- exit for every m people, k -- start Person Number :";

Cin> N> m> K;

Int * A = new int [N];

For (INT I = 1; I <= N; I ++)

A [I] = 1;

Joseph FUS (n, m, K, );

Delete [];

Return 0;

}

**(3) linked list Solution**

# Include <iostream. h>

# Include <stdlib. h>

Typedef struct Node

{

Int data;

Struct node * next;

} Lnode, * linklist;

// N indicates the total number, M indicates the number shouted by the column creator, and K indicates the number of the first person who starts reporting the number.

Void Joseph phring (int n, int M, int K)

{

Linklist P, R; // P indicates the current node, r indicates the secondary node, and points to the forward node of P.

Linklist list = NULL; // list is the header node, which is a null pointer before a linked list is created.

For (INT I = 1; I <= N; I ++) // create a cyclic queue

{

P = (linklist) malloc (sizeof (lnode ));

P-> DATA = I;

If (list = NULL)

List = P;

Else

R-> next = P;

R = P; // create each node in the linked list

}

P-> next = List; // set up to loop the queue

P = List; // point P to the header node.

// Move the current pointer to the first reporter

For (I = 1; I <K; I ++)

{

R = P;

P = p-> next;

}

// Delete queue nodes cyclically

While (p-> next! = P)

{

For (I = 1; I <m; I ++)

{

R = P;

P = p-> next;

}

R-> next = p-> next;

Cout <p-> data <Endl;

Free (P );

P = r-> next;

}

Cout <Endl <"the remaining person is:" <p-> data <Endl;

}

Int main ()

{

Int n, m, K;

Cout <"Enter the parameter: n -- total number, m -- exit for each M, k -- start number:" <Endl;

Cout <"requirement: n> 0; 1 = <k <= n." <Endl;

Cin> N> m> K;

Cout <"the sequence of departure is as follows:" <Endl;

Joseph ring (n, m, k );

System ("pause ");

Return 0;

}

////////////////////////////////////////

# Include <iostream>

Using namespace STD;

Void yuesefu (int A [], int N, int M, int S)

{

Int K = N; // The total number.

Int I = M-1 + s-1;

Int C = 0, P;

While (k> 1)

{

I % = N;

Cout <"no." <++ C <"number:" <A [I] <Endl;

A [I] = 0;

K --;

P = 1;

While (P <= m)

{

I ++;

If (A [I % N]! = 0)

P ++;

}

}

For (INT I = 0; I <n; I ++)

If (A [I]! = 0)

{

Cout <"the last rest is:" <A [I] <Endl;

Break;

}

}

Int main ()

{

Int n, m, K;

Cout <"N (total), m (report), and K (start person ):";

Cin> N> m> K;

Int * A = new int [N];

For (INT I = 0; I <n; I ++)

A [I] = I + 1;

Yuesefu (A, n, m, k );

Delete [];

A = 0;

Return 0;

}