[title link]
ybt 2037: [example 5.4] Joseph problem
ybt 1334: [example 2-3] ring counting
Rogue 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) { //... }
2. Queue
3. Linked list
Inspection: single linked list, circular linked list, stl list
[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[1005] = {};//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[1005];//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; }