n个人围成一圈,按1到n的顺序编号。从第一个人开始报数(从1到m报数),凡报到m的人退出圈子,问最后留下的是原来的第几号。用c++来实现
时间: 2024-02-21 19:58:06 浏览: 81
好的,这道题目是经典的约瑟夫问题,可以用循环链表和递归两种方式实现。以下是用循环链表实现的C++代码:
```c++
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
Node(int x) : data(x), next(nullptr) {}
};
Node* create(int n) {
Node* head = new Node(1);
Node* tail = head;
for (int i = 2; i <= n; i++) {
Node* node = new Node(i);
tail->next = node;
tail = node;
}
tail->next = head; // 将链表的尾节点指向头节点,形成循环链表
return head;
}
int josephus(Node* head, int m) {
Node* p = head;
while (p->next != p) { // 当链表中只剩一个节点时结束循环
for (int i = 1; i < m - 1; i++) {
p = p->next;
}
Node* temp = p->next;
p->next = temp->next; // 将当前节点的下一个节点从链表中删除
delete temp; // 释放被删除节点的内存
p = p->next; // 将指针指向下一个节点
}
return p->data;
}
int main() {
int n = 10;
int m = 3;
Node* head = create(n);
int ans = josephus(head, m);
cout << "The last one is " << ans << endl;
delete head; // 释放链表的内存
return 0;
}
```
这段代码中,`create`函数用于创建一个有`n`个节点的循环链表,并返回头节点的指针。`josephus`函数用于从循环链表中每隔`m-1`个节点删除一个节点,直到链表中只剩下一个节点,最后返回剩下节点的编号。在主函数中,我们调用`create`函数创建了一个有`10`个节点的循环链表,然后调用`josephus`函数从链表中每隔`2`个节点删除一个节点,最后输出剩下的节点的编号。
阅读全文