# Informatics Aosai yibentong 2037: [example 5.4] Joseph problem / 1334: [example 2-3] circle counting / Luogu P1996 Joseph problem

## [title test site]

#### 1. Loop through the array

Assuming that the array subscript is 1~n, after the loop control variable i traverses from 1 to N, it is re assigned to 1, and then traverses to N. repeat this process until a certain condition is met, and jump out of the loop.

```int i = 1;
while(Some cyclic condition)
{
//...
i++; //Or write this paragraph as: I = I + 1 = = n? 1 : i + 1;
if(i == n)
i = 1;
}
```

If the array subscript is 0~n-1, it can be written as:

```for(int i = 1; Some cyclic condition; i = (i + 1)%n)
{
//...
}
```

## [problem solving ideas]

#### Solution 1: loop through the array

Set a Boolean array to indicate whether a person has been listed. Loop through the array. If you encounter a person who is not in the column, skip. Start from the current position, find m-1 person in the column, and then find the next person in the column, that is, the person to be out of the column. Output the person number and list it. Repeat the above process n times, one person at a time.

#### Solution 2: using queues

Suppose these n people form a team, count the number at the head of the team, count each person, let this person out of the team, and then join the team at the end of the team. When counting the m-th person, output the person's number and let the person out of the team and no longer join the team. Repeat the above process n times.

#### Solution 3: Ring queue

In the simulation, each person, as a node, points to the next node in turn to form a single linked list. The next node of the last node is set as the first node to form a ring linked list. In the process of the simulation problem, set a pointer to the first node, move the pointer backward m-1 times, point to the m-th node, output the value of the node pointed to at this time, then delete the node and point to the next node, and cycle n times.

## [solution code]

#### Solution 1: loop through the array

```#include <bits/stdc++.h>
using namespace std;
int main()
{
bool isOut = {};//isOut[i]: whether the i-th person is listed or not. The initial value is false and there is no listing. Use subscript: 0~n-1
int n, m, p = 0;//p: Current location
cin >> n >> m;
for(int i = 1; i <= n; ++i)//Output n times in total
{
for(int j = 0; j < m-1; ++j)//Find m-1 someone in the column
{
while(isOut[p] == true)
p = (p+1)%n;
p = (p+1)%n;
}//At this time, p points to the next position of the m-1 number
while(isOut[p] == true)//Find the next person, the m-th person in the list
p = (p+1)%n;
isOut[p] = true;//At this time, p points to the m-th person and asks that person to be listed
cout << p+1 << ' ';//The subscript starts from 0, the person number starts from 1, and the subscript is changed to the person number. You need to add 1
}
return 0;
}
```

#### Solution 2: using queues

```#include <bits/stdc++.h>
using namespace std;
int main()
{
queue<int> que;
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; ++i)
que.push(i);
for(int i = 1; i <= n; ++i)
{
for(int i = 1; i <= m - 1; ++i)
{//After the leader of the team is out of the team, he will join the team to the end of the team
que.push(que.front());
que.pop();
}
cout << que.front() << ' ';//At this time, the head of the team is the person to be in line
que.pop();
}
return 0;
}
```

#### Solution 2: circular linked list

• Writing method 1: circular single chain table
```#include <bits/stdc++.h>
using namespace std;
struct Node
{
int val;
int next;
};
Node node;//Node pool
int p = 1;
int main()
{
int n, m;
cin >> n >> m;
int first, tail, np;//First: point to the first node tail: tail pointer np: new node address
np = p++;//Location of the first node
node[np].val = 1;
first = tail = np;
for(int i = 2; i <= n; ++i)
{//Construction of single linked list by tail interpolation
np = p++;
node[np].val = i;
node[tail].next = np;
tail = np;
}
node[tail].next = first;//The next of the last node points to the first node to form a ring linked list
int sel = tail, del;//Judge whether to delete the next node of sel. Initially, the next node of sel is the first node, del: the node to be deleted
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m-1; ++j)//Initially, the next of sel is the first node. After moving backward m-1 times, the next of sel is the m-th node.
sel = node[sel].next;
del = node[sel].next;//The next node del of sel is the node that should be deleted
node[sel].next = node[del].next;//Delete node del. After deletion, the next node of sel is the first of the m nodes to be seen below
cout << node[del].val << ' ';//Output the value of the deleted node, that is, the number of the person listed
}
return 0;
}
```
• Writing 2: stl list is actually a two-way linked list
```#include<bits/stdc++.h>
using namespace std;
int main()
{
list<int> li;
int n, m, ct = 0;//ct: count, how many times
cin >> n >> m;
for(int i = 1; i <= n; ++i)//Insert 1~n into the linked list by tail insertion
li.push_back(i);
list<int>::iterator it = li.begin(), ie;//it: iterator, pointing to the first node, ie: pointing to the node to be deleted
while(li.empty() == false)//As long as the linked list is not empty, people will continue to be listed (delete nodes)
{
ct++;//Number of people
if(ct == m)//If you count to the m-th person
{
ie = it;//Ready to delete the node it points to at this time
cout << *ie << ' ';//Output node value, that is, person number
it--;//it points to the previous node of ie
li.erase(ie);//Delete ie node
ct = 0;//Re count
}
it++;//it points to the next node
if(it == li.end())//If it has traversed to the end of the linked list, then re point to the first node of the linked list to simulate the traversal of the ring linked list
it = li.begin();
}
return 0;
}
```

Tags: C++

Posted on Sun, 28 Nov 2021 12:40:42 -0500 by Billett