Tema Descripción
Supongamos que hay n personas sentadas alrededor de la mesa redonda, y la persona en cierta posición k comienza a contar, y la persona que cuenta hasta mm se pondrá de pie. La siguiente persona, es decir, la persona en la posición original m+1, comienza a contar desde 1 y luego la persona que cuenta hasta m se pone de pie. Repita uno por uno hasta que todas las personas se pongan de pie. Trate de diseñar un programa para encontrar el orden de estas n personas.
Requisito 1: Use una lista enlazada circular para resolver.
Requisito 2: puede utilizar el método de simulación para simular una lista enlazada circular.
Requisito 3: No es necesario utilizar la definición y el uso de la clase de lista enlazada circular.
ingrese la descripción
La entrada tiene solo una línea y son tres números enteros positivos n, k, m separados por espacios, y su significado es el anterior.
descripción de salida
Hay n líneas en total, que indican el orden de las n personas.
Muestras de entrada y salida
ingresar
3 5 8
producción
3
2
1
Para esta pregunta, puede escribir una lista de doble enlace en c para lograrlo. La idea es tener varios bucles. El primer bucle encuentra la posición del conteo inicial, y el segundo bucle cuenta y sale. La condición final es que solo queda uno en la lista enlazada. Agregue el último elemento y luego envíe el último elemento después de que finalice el bucle. Preste atención a controlar la cantidad de bucle.
#include <iostream>
using namespace std;
struct Node
{
int data;
Node *pNext;
};
int main()
{
int n, k, m, i; //n个人从k位置开始报数,数到m出列
Node *p, *q, *head;
cin >> n >> k >> m;
//初始化链表
Node * first = (Node *)new Node;
p = first;
first->data = 1;
for (i = 2; i <= n; i++)
{
q = new Node;
q->data = i;
p->pNext = q;
p = p->pNext;
}
p->pNext = first;
p = first; //形成循环链表
for (i = 1; i <= k - 1; i++) //找到第k个位置的那个人,即初始位
p = p->pNext;
while (p != p->pNext) //只剩下一个结点的时候停止(剩下一个结点时头尾一致)
{
for (i = 1; i < m - 1; i++) //开始报数,循环结束时 p为第m-1个
{
p = p->pNext;
}
//所以q为第m个,出列
q = p->pNext; //q为要出队的元素
cout << q->data << endl;
p->pNext = q->pNext;
delete q;
p = p->pNext; //从第m+1个开始重新报数
}
cout << p->data << endl; //循环结束,只剩最后一个元素,输出
return 0;
}
Al principio, quería usar contenedores de lista para escribir, lo cual también es muy conveniente, pero la idea no es tan simple y clara. El algoritmo que implementé usando contenedores de lista se publica a continuación. El punto a tener en cuenta es que cuando se usan iteradores para recorrer, preste atención a los límites, incluido el último Allí, recuerde usar un iterador más para juzgar si la siguiente posición es la última, de lo contrario, se desordenará.
#include <iostream>
using namespace std;
#include <list>
list<int> l1;
int main()
{
int n,k,m;
int i=1;
cin >> n >> k >> m;
//循环链表初始化
for(i=1;i<=n;i++)
{
l1.push_back(i);
}
//找到起始位置k的那个人
list<int>::iterator it=l1.begin();
for(int j=1;j<k;j++)
{
it++;
if(it==l1.end())
{
it=l1.begin();
}
}
//开始报数 用两个循环 外层循环为总共链表中的个数,内层循环为每一次报数淘汰过程
for(int l=1;l<n;l++)
{
for(int j=1;j<m;j++)
{
it++;
if(it==l1.end())
{
it=l1.begin();
}
}
cout<< (*it)<<endl;
//多加一个判断,防止这个数是在末尾
list<int>::iterator it_1 = it;
it_1++;
if(it_1==l1.end())
{
l1.erase(it);
it=l1.begin();
}else{
it=l1.erase(it); //erase返回值是删除位置的下一个位置,刚好就是从这里继续开始报数,不过要多加一个判断,万一这个位置在末尾
}
}
cout<< l1.back() <<endl;
// 请在此输入您的代码
return 0;
}
Parece que el recorrido también se puede implementar con otras funciones, pero aún no estoy muy familiarizado con él. Aprenderé más cuando me conecte y lo actualizaré más tarde. Comentarios y sugerencias son bienvenidos.