Joseph Question:
The user enters the M,n value, starting from 1 to N, the number of cycles, each number to m output that value, until the full output. Write the C program.
#include <stdio.h>#include<stdlib.h>typedefstructringnode{intPOS; structRingnode *Next;} Ring,*Ring;voidCreate (Ring Head,intcount) {Ring cur= NULL, tail =NULL; inti =1; Tail=Head; while(--count >0) {cur= (Ring)malloc(sizeof(ring)); I++; Cur-pos =i; TailNext =cur; Tail=cur; } TailNext =Head;}voidPlay (Ring Head,intm) {Ring cur,tail; inti =1; Cur= Tail =Head; while(cur!=NULL) { if(i = =m) {printf ("\ n%d",cur->POS); TailNext = curNext; Free(cur); Cur= TailNext; I=1; } Tail=cur; Cur= cur->Next; if(Tail = =cur) {printf ("\ n%d",cur->POS); Free(cur); Break; } I++; }}intMainvoid) {Ring head=NULL; intm =0, n =0; printf ("-------------------the game start-------------------\ n"); printf ("N (person count) ="); scanf ("%d",&N); printf ("M (out count) ="); scanf ("%d",&m); if(N <=0|| M <=0) {printf ("input error!\n"); System ("Pause"); return 0; } head= (Ring)malloc(sizeof(ring)); Head->pos =1; Head->next =NULL; Create (Head,n); printf ("\norder:"); Play (HEAD,M); printf ("\ n"); System ("Pause"); return 0;}
The simplification of the problem, if only to find the final winner.
Thought: Inductive to the problem of mathematics. The original said very good, or directly copy it, because the search for half a day did not find the original author, so can not add a reference address, if the eldest brother see here, please tell me, brother immediately join the quote link:)
There is one thing in common with either a linked list or an array implementation: to simulate the entire game process, not only is the program more annoying, but the time complexity is as high as O (nm), and when the n,m is very large (for example, millions, tens of thousands), there is almost no way to produce results in a short period of time. We noticed that the original problem was merely to ask for the serial number of the last winner, rather than to mock the whole process. Therefore, if we want to pursue efficiency, we must break the routine and implement a mathematical strategy.
In order to discuss the convenience, the problem is changed slightly, does not affect the original intention:
Problem description: N Person (number 0~ (n-1)), starting from 0 count, reporting (M-1) exit, the remainder continues to count off from 0. The winner's number.
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)
With this formula, all we have to do is calculate the value of F[i] from the 1-n order, and the final result is f[n]. Because real life numbers always start from 1, we output f[n]+1
Because it is a step-by-step recursive and does not need to save each f[i], the program is also exceptionally simple:
Learn from the following:
#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);}
The time complexity of the algorithm is O (n), which has been greatly improved compared with the simulation algorithm. Count N,m equals 1 million, 10 million is not a problem. It can be seen that the proper use of mathematical strategies not only makes programming simple, but often multiplies the efficiency of algorithm execution.
By contrast, the superiority of solution two is self-evident, and it is important to explain mathematics.
On the question of Joseph, the number of M-values is reported in the dequeue.