有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
链表最适合解决删除节点问题,这里将链表成环,然后计数删除对应的节点
#include <iostream>
using namespace std;
// 定义链表
struct LinkNode {
int val;
struct LinkNode* next;
// 构造函数
LinkNode(int x):val(x), next(nullptr){}
LinkNode():val(0), next(nullptr){}
};
void test(int n) {
if (n == 1) {
cout << n << endl;
return;
}
// 构建链表
LinkNode* head = new LinkNode(1);
LinkNode* curNode = head;
for (int i = 2; i <= n; i++) {
curNode->next = new LinkNode(i);
curNode = curNode->next;
}
// 构建成环形链表
curNode->next = head;
int count = 1;
curNode = head; // 要删除的节点
LinkNode* pre = nullptr; // 要删除节点的前一个节点
while (curNode != pre) {
if (count % 3 != 0) {
pre = curNode; // 移动前一个节点
curNode = curNode->next; // 移动当前节点
count++;
} else {
// 这里要删除了
LinkNode* temp = curNode; // 记录当前节点
pre->next = curNode->next; // 删除节点的下一个节点指向删除节点的下一个节点
curNode = curNode->next; // 移动当前节点
delete temp; // 删除节点
count = 1; // 计数器重置
}
}
// 这个while处理完,pre==curNode
// cout << curNode->val;
cout << pre->val;
}
int main(int argc, char** argv) {
int n;
cin >> n;
test(n);
return 0;
}