题目链接:7-28 猴子选大王
一. 题目
1. 题目
2. 输入输出样例
3. 限制
二、代码
1. 代码实现
#include <iostream>
using namespace std;
// 链表里的节点类
class node {
private:
unsigned int num;
node* next;
public:
node(unsigned int num) {
this->num=num;
this->next=this;
}
node *getNext() {
return next;
}
void setNext(node *p) {
// 若此节点next已存在,需要释放
// if (next) delete next;
this->next = p;
}
int getValue() {
return num;
}
};
// 带首尾节点的循环链表
class list {
private:
node* head;
node* tail;
int length;
public:
list() {
head = tail = 0;
length = 0;
}
node *GetHead() {
return head;
}
node *GetTail() {
return tail;
}
int len() {
return length;
}
void insertHead(node *p) { // 插入头节点
if (head) { // 若头节点存在
p->setNext(head);
tail->setNext(p);
head = p;
} else {
head = tail = p;
}
length ++;
}
void insertTail(node *p) { // 插入尾节点
if (head) { // 若头节点存在
p->setNext(head);
tail->setNext(p);
tail = p;
} else {
head = tail = p;
}
length ++;
}
};
// 选国王算法
int monkeyKing(list *monkeys) {
node *p = monkeys->GetHead();
int num = 0;
int len = monkeys->len();
while (len > 1) { // 只剩一个时退出循环
num++;
if (num == 2) {
// 当前报数为2,下一位报数为3
// 将报数为3的猴子从链表移除(2号的下一位变更为3号的下一位)
p->setNext(p->getNext()->getNext());
num = 0;
len --;
}
p = p->getNext();
}
return p->getValue(); // 返回猴王的序号
}
int main(void) {
int num;
list *monkeys = new list();
cin >> num;
// 链表初始化
for (int i = 1; i <= num; i++) {
monkeys->insertTail(new node(i));
}
cout << monkeyKing(monkeys) << endl;
delete monkeys;
return 0;
}