C ++ algorithm simulation for the problem of Joseph's ring

Source: Internet
Author: User
The time complexity of this algorithm is O (n), which has greatly improved compared with the simulation algorithm. N, m is equal to 1 million, and 10 million is not a problem. It can be seen that the proper use of mathematical strategies not only makes programming simple, but also improves algorithm execution efficiency exponentially.

Problem Description: Number 1, 2 ,........., N people in n circle clockwise, each holding a password (positive integer ). Select a positive integer from the beginning as the maximum value of m. start from the first person and start from 1 Clockwise. when reporting to m, stop reporting. The person who reported m is listed, and his password is used as the new m value, starting from the next person in the clockwise direction to record from 1 until all the people are listed. Design a program to find out the column sequence.

Both using linked lists and array implementations have one thing in common: to simulate the entire game process, not only is it annoying to write programs, but also the time complexity is as high as O (nm). when n, when m is very large (for example, millions or even tens of millions), there is almost no way to produce results in a short time. We noticed that the original problem only requires the serial number of the final winner, rather than simulating the whole process. Therefore, if efficiency is to be pursued, we must break the regular rules and implement some mathematical strategies.

To facilitate the discussion, change the problem slightly without affecting the original intention:

Problem Description: n people (No. 0 ~ (N-1), reporting starts from 0, reporting ends from M-1), and reporting continues from 0. Calculate the number of the winner.

We know that after the first person (number must be m % n-1) is listed, the remaining N-1 person forms a new Joseph ring (starting with a person numbered k = m % n ): k + 1 k + 2... n-2, n-1, 0, 1, 2 ,... k-2, and 0 from k.

Now let's convert their numbers:

k --> 0 k+1 --> 1 k+2 --> 2 ... ... k-2 --> n-2 k-1 --> n-1 

After the transformation, it will completely become a subproblem of (n-1) the number of individual reports. if we know the solution of this subproblem: for example, x is the final winner, so it's just n people's situation to change x back based on the table above ?!! The formula for changing back is very simple. I believe everyone can introduce it: x' = (x + k) % n.

How can I solve the problem of (n-1) number of personal reports? Yes, as long as you know (n-2) the individual's solution. (N-2) what about personal solutions? Of course it is the first (n-3) situation ---- this is obviously a reverse push problem! Well, the idea is coming out. the recursive formula is as follows:

F [I] indicates the number of the final winner after I personally play the game. The final result is f [n].

Recurrence formula:

f[1]=0; f[i]=(f[i-1]+m)%i; (i>1)

With this formula, we need to calculate the value of f [I] from the 1-n order, and the final result is f [n]. In actual life, the number always starts from 1, and we output f [n] + 1.

The procedure is as follows:

# Include
 
  
Using namespace std;/* characters, including their own numbers, passwords, and pointers to the next */struct Person {int num; int cipher; person * next;}; Person person [7]; void Circle (); void main () {Circle (); int m; // The start password value (cin> m; Person * currentPerson) entered at the start. // you can easily search for Person * prePerson; currentPerson = & person [0] on the character linked list. // at the beginning, point the pointer to the first and last prePerson = & person [6]; while (currentPerson! = PrePerson) {for (int I = 1; I
  
   
Next;} m = currentPerson-> cipher; cout <
   
    
Num <""; // Number of the output character prePerson-> next = currentPerson-> next; // modify the linked list to remove the selected character from currentPerson = prePerson-> next ;} cout <
    
     
Num; // output the number of the last character (cin> m;} void Circle () // edit the character attributes {for (int I = 0; I <7; I ++) {person [I]. num = I + 1; person [I]. next = & person [I + 1];} person [6]. next = & person [0]; // point the pointer of the last character to the first one, forming a circular linked list person [0]. cipher = 3; person [1]. cipher = 1; person [2]. cipher = 7; person [3]. cipher = 2; person [4]. cipher = 4; person [5]. cipher = 8; person [6]. cipher = 4 ;}
    
   
  
 

The time complexity of this algorithm is O (n), which has greatly improved compared with the simulation algorithm. N, m is equal to 1 million, and 10 million is not a problem. It can be seen that the proper use of mathematical strategies not only makes programming simple, but also improves algorithm execution efficiency exponentially.

Address of this article: http://www.nowamagic.net/librarys/veda/detail/462,welcome.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.