Source: "Sword point offer" face question 45
Title: 0, 1, ... , n-1 this n number of words into a circle, starting with the number 0 each time you remove the number m from this circle. Find the last number left in this circle.
Solution One: A classical method of simulating a circle with a ring-linked list. This method requires M-step operations for each number of deletions, with a total of n numbers, so the total time complexity is O (MN). At the same moment, this idea also requires an auxiliary list to simulate the circle, whose spatial complexity is O (n).
intLastremaining (unsignedintN, unsignedintm) {if(N <1|| M <1) return-1; List<int>Nums; for(inti =0; I < n; i++) Nums.push_back (i); List<int>::iterator iter =Nums.begin (); for(inti =0; I < n-1; i++) { for(intj =1; J < M-1; ++j) {iter++; if(iter = =nums.end ()) ITER=Nums.begin (); } list<int>::iterator Next = + +ITER; --ITER; if(Next = =nums.end ()) Next=Nums.begin (); Nums.erase (ITER); ITER=Next; } return*iter;}
Solution Two:
We know that the first person (the number must be m%n-1) after the dequeue, the rest of the n-1 individuals formed a new Joseph Ring (starting with the person numbered k=m%n):
K k+1 k+2 ... n-2, n-1, 0, 1, 2, ... k-2 and reported 0 from K.
Now let's do a conversion of their numbers:
K--0
K+1-1
K+2-2
...
...
K-2-N-2
K-1-N-1
After the transformation has completely become the (n-1) personal count of the sub-problem, if we know the solution of this sub-problem: for example, X is the final winner, then according to the above table to turn this x back is not exactly the solution of n personal situation?! The formula to change back is very simple, I believe everyone can push out: X ' = (x+k)%n
How to Know (n-1) The solution of the problem of personal count off? Yes, as long as you Know (n-2) the individual's solution. (n-2) A personal solution? Of course, the first thing to ask (n-3)----This is obviously a backward problem! Okay, here's the idea, here's the recursive formula:
Make f[i] means I personally play the game reported M exit the last winner's number, the final result is naturally f[n]
Recursive formulas
f[1]=0;
f[i]= (f[i-1]+m)%i; (i>1)
#include <stdio.h>intMain () {intN, M, I, S =0; printf ("N M ="); scanf ("%d%d", &n, &m); for(i =2; I <= N; i++) {s= (s + m)%i; } printf ("\nthe winner is%d\n", s+1);}
Resources:
1. http://www.cnblogs.com/EricYang/archive/2009/09/04/1560478.html
"Algorithmic topic", Joseph Ring question