约瑟夫(Joseph)环问题
编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。
如果不要求用单向循环链表的话可以有更加优雅的解法。
#include "pch.h"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
class node {
public:
node * pnode = 0;
int secret;
int id = 1;
};
int main()
{
int numberOfNode; //用户输入的数据个数
int m; //初始的数字
int id = 1; //节点标号
cin >> m;
cin >> numberOfNode; //应该不会只有一个节点吧
node * head = new node;
node * prev = head;
node *now = 0;
cin >> head->secret;
int numberOfNode1 = numberOfNode - 1;
while (numberOfNode1--) {
now = new node;
cin >> now->secret;
now->id = ++id;
prev->pnode = now;
prev = now;
}
now->pnode = head;
//初始化循环链表
node * p = head;
prev = nullptr;
while (numberOfNode) {
int count = 1;
while (count != m) {
count++;
prev = p;
p = p->pnode;
}
//模拟数数
prev->pnode = p->pnode; //去掉一个节点
m = p->secret;
cout << p->id << " ";
node *tmp = p->pnode;
delete p;
numberOfNode--;
p=tmp;
}
return 0;
}
测试数据
20 7 3 1 7 2 4 8 4 输出: 6 1 4 7 2 3 5