April Fools ' Day with oneself opened a very big joke, a few days did not write the procedure, today continues! Josephus the problem is that n people in a circle heat transfer potatoes, first agreed to a number m, when the transmission of M-time to take the potatoes out of the person, and then the potato to the next person, the game continues, until the end of only one person, to find out the sequence (in the order of the exit).
This problem can be implemented in an array, but it is necessary to mark the elements that represent the outgoing person, and to check if the element is marked as out if it is not traversed, the program will run for a slower time. Another way to do this is to use a linked list and delete the outgoing nodes each time. Such a solution is very straightforward, just focus on the nodes in the list, because the nodes in the list are not out. Deleting a node is just a pointer adjustment, very quickly, but freeing up deleted nodes takes a lot of time, and when the input n is large, it takes a significant amount of effort. Therefore, the combination of a linked list and arrays can overcome the shortcomings of the two methods.
The way to combine is to put the list in an array! Initially, each element's next pointer points to the next element of the array, and the last one points to the first (what we need is a circular list). This allows us to implement jumping access in the array without having to worry about whether the node being accessed is marked as out, and finally freeing up the space occupied by the array at once, without the release of the Chain list node!
#include "stdafx.h"#include <iostream>Using namespace Std;struct person{intId person*Next;}; struct person_list{intCount person* first; person* Last;}; person_list* Init (intN) {person* p = new Person[n]; for(inti =0; I < n-1; ++i) {p[i].id = i +1; P[i].Next= &p[i+1]; } P[n-1].id = n; P[n-1].Next= &p[0]; person_list* persons = new Person_list; Persons->count = n; Persons->first = p; Persons-> Last= &p[n-1];returnPersons;}int* Solve (intNint m){if(N <1||m<0)returnNULL; person_list* persons = init (n); person* first = persons->first; person* t = first;intCount = persons->count;int *losers= newint[n];intj =0; while(Count >1) {person*Q= NULL; for(inti =0; I <m; ++i) {Q= First; First = First->Next; }if(first = = Persons->first) {Persons->first = first->Next; Persons-> Last= persons->first; }Else if(First = = Persons-> Last) {Q-Next= first->Next; Persons-> Last=Q; }Else{Q-Next= first->Next; }--count; Losers[j++] = first->id; First = First->Next; } Losers[j] = persons->first->id;Delete[]t;DeletePersonsreturnLosers;}int_tmain (intARGC, _tchar* argv[]) {intn =5,m=1;int* Losers = Solve (n,m); for(inti =0; I < n; ++i) {cout<<losers[i]<<"'; } cout<<endl;Delete[]losers;return 0;}
The last element of the losers array in the program holds the last winning person, before the exit sequence.
Many things in life are like writing programs, where there is no bug, but bugs are always fixed, right?
One question per day 14: Josephus problem under the combination of array and chain list scheme