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

[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;
}

Tags: C++

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