n个人围成一圈顺序编号,从1号开始按1、2、3......顺序报数,报p者退出圈外,其余的人再从1、
时间: 2024-09-23 12:12:34 浏览: 117
jenkins 2.346.1 支持jdk1.8的最后一版本,公司还在用jdk1.8的可以考虑
这是一个经典的约瑟夫问题,也称为“丢手绢问题”。解决这个问题的方法有很多,其中一种比较常用的方法是使用环形链表。具体思路是:先将N个人用链表连接起来,然后从第一个人开始报数,每报到p时,将该节点从链表中删除,直到链表中只剩下一个节点为止。最后剩下的那个节点即为胜者。下面是具体的实现方法:
1.定义一个结构体表示链表节点,包含一个整型变量表示节点编号和一个指向下一个节点的指针。
2.创建一个长度为N的环形链表,将每个节点的编号赋值为对应的顺序编号。
3.从第一个节点开始,依次报数,每报到p时,将该节点从链表中删除。
4.重复步骤3,直到链表中只剩下一个节点为止。
5.输出剩下节点的编号,即为胜者的原序号。
具体实现可以参考以下代码:
```
#include <iostream>
using namespace std;
//定义链表节点结构体
struct Node {
int num; //节点编号
Node* next; //指向下一个节点的指针
};
int main() {
int m, n, p;
cin >> m; //输入测试数据组数
while (m--) {
cin >> n >> p; //输入总人数和报数的数字
Node* head = new Node(); //创建头节点
head->num = 1;
Node* cur = head;
for (int i = 2; i <= n; i++) { //创建环形链表
Node* node = new Node();
node->num = i;
cur->next = node;
cur = node;
}
cur->next = head; //将链表首尾相连,形成环
Node* pre = cur; //pre指向链表的最后一个节点
cur = head; //cur指向链表的第一个节点
while (pre != cur) { //当链表中只剩下一个节点时结束循环
for (int i = 1; i < p; i++) { //依次报数
pre = cur;
cur = cur->next;
}
pre->next = cur->next; //将当前节点从链表中删除
cout << cur->num << " "; //输出删除节点的编号
Node* temp = cur; //释放删除节点的内存空间
cur = cur->next;
delete temp;
}
cout << cur->num << endl; //输出胜者的原序号
delete cur; //释放胜者节点的内存空间
}
return 0;
}
```
阅读全文