Joseph Problem (detailed solution) and Joseph Problem Solution

Source: Internet
Author: User

Joseph Problem (detailed solution) and Joseph Problem Solution
Preface

I learned the queue these days, so I tried Joseph Problem, And then I failed to get through it. Finally, after dialing, I passed. I am deeply impressed with the use of queues. We recommend that you try to solve this problem if the queue trainer is working.

 

Body

 

 

Joseph Problem (35 points): Suppose there are N people in a circle, then the first person kills the second person, the knife is used to the third person, and the third person kills the fourth person, and so on ...... first Note: difficulty 1: What data structure will we use in a circle? So many people should first think of using arrays, right? But how to enclose them in a circle? The point is, can we keep moving the previous one to the back to form a circle? Right? Difficulty 2: did the previous person kill the last one? In general, we should want to remove the element of the person who was killed, and then move the previous element to the back, but this will not achieve the effect of forming a circle. The point is, that's to say, they killed the person from the beginning, right! It's okay. I killed it, and put it to the very end of the array. Okay. difficulties have been discussed.

Subject content:

Joseph problem.

There are N people at the beginning of the hypothetical settings, and the number is between 1 and 1 ~ N,

In the sort order, the data is converted into a circle at a certain time.

At the beginning of the attack, the first person in the workshop took the knife.

In the future, each knife will be pushed down to M people,

The person who finally gets the knife will take down his next man,

After the attack is completed, the knife will be handed over to the next person in the attack.

In this case, it is the end.

Maybe there will be a lot of progress, until only the last person is left.

 

Example 1: N = 5, M = 2

First Tip: 3 rows for the knife, 4 rows for the knife, and 5 rows for the knife (1 2 3 5)

Second tip: 2 rows for the knife, 3 rows for the knife, and 5 rows for the knife (1 2 5)

Third party: 2 Party A with a knife, 5 Party A with a knife, and 1 party with a knife (1 2)

Fourth challenge: the knife is given to 1 hour, 2 hours are rejected, and the last 1 day is alive.

Example 2: N = 4, M = 3

The first tip: 4 rows for the knife, 1 hour for the knife, and 2 seconds for the knife (2 3 4)

Second tip: the knife is pushed to 2 blocks, the knife is pushed to 4 blocks (2 4)

The third challenge: the knife is given to 2 users, 4 Users are rejected, and the last 2 users are alive.

 

Input Format:

The first line is a data T, which indicates the data volume of the data.

Next, there will be TB-level resources, and every row of resources will be added,

There will be two numbers N, M, separated by spaces.

Data Metadata:

T <1, 1000

0 <N <= 1000

0 <M <= 1000

 

Output Format:

Write a row of data to add the total number of people who survive each row.

 

Input example:

3

5 2

4 3

8 4

 

Output example:

4

Time Limit: Ms memory limit: KB

Let's try it out first. It is better to read the article again!

 

Understanding the question: Let's look at the first example: After passing two people with a knife, the third person is killed. Adding a circle is equivalent to killing two people and moving them to the back. Then it becomes the first problem, right? Okay. Start writing code.

First, we will consider killing people.

1 int Dequeue () {2 int z; // records which person is killed. Otherwise, if there is no record, how can I move it to the next 3 z = ch [Head]? 4 Head = (Head + 1) % 1000; // point the Head to the next person, which is equivalent to the person in this circle who does not have 5 Number_of_Items --; // The total number of users minus 6 return z; 7}

Next, consider inserting the following action:

1 void Enqueue (int x) {2 if (Number_of_Items = 0) {// if the array is empty, redefine the queue header and Tail 3 Tail = Head = 0; 4 ch [0] = x; // then add it to 5} else {6 Tail = (Tail + 1) % 1000; // point the end of the team to the next one, used to store new users 7 ch [Tail] = x; 8} 9 Number_of_Items ++; // total number of users plus 10}

The next step is the overall design.

Scanf ("% d", & a, & B); // enter the total number of people and the number of people to be transferred
For (int I = 1; I <= a; I ++) Enqueue (I); // put these people in the array for (int I = 1; I <= A-1; I ++) {// each round of killing a person, killing n-1 individual for (int k = 0; k <B % Number_of_Items; k ++) {j = Dequeue (); Enqueue (j) ;}// each time a user B is moved to the end j = Dequeue (); Enqueue (j ); // as mentioned in the foreshadowing, kill two people and put the first person behind the array. }

Note:

1. When adding array elements, consider when the array is empty.

2.

for(int k=0; k < b%Number_of_Items; k++) {                j = Dequeue();                Enqueue(j);            }

Note that this code is stuck in this place for a long time. I don't see it. When B is very large, it takes a long time to run. Here there are three for loops, so I tried to reduce the complexity of the algorithm. So we found that we can optimize B, which is the key point.

3. When you add an array element each time, add one to the total number of elements. When you delete an array element, subtract one from the total number.

 

Okay. Then write the total code:

# Include <stdio. h> int ch [1000]; int Head, Tail, Number_of_Items; void Enqueue (int x) {if (Number_of_Items = 0) {Tail = Head = 0; ch [0] = x;} else {Tail = (Tail + 1) % 1000; ch [Tail] = x;} Number_of_Items ++;} int Dequeue () {int z; z = ch [Head]; Head = (Head + 1) % 1000; Number_of_Items --; return z;} int main () {int n, j,, b; int answer; int sum = 0; scanf ("% d", & n); for (int I = 0; I <n; I ++) {scanf ("% d", & a, & B); ch [1000] = 0; // note that every update to the array Number_of_Items = 0; // for the total number of updated Tail = Head = 0; for (int I = 1; I <= a; I ++) Enqueue (I); for (int I = 1; I <= A-1; I ++) {for (int k = 0; k <B % Number_of_Items; k ++) {j = Dequeue (); Enqueue (j );} j = Dequeue (); Enqueue (j);} sum + = ch [Head];} printf ("% d", sum); return 0 ;}

 

Note: after each array is used up, the update value must be set to 0 and the total number must be updated.

Summary

This topic focuses on how to reduce algorithm complexity and optimize some of the variables. I also learned more about the optimization after others.

 

14:14:02

 

 

Related Article

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.