——by A Code Rabbit
Description
- 有 n 个人(从0到 n – 1)排成一队,队头和队尾相连,变成一个圈。
- 然后有两个 official ,一个从队头开始顺序点人头,一个从队尾开始逆序点人头。
- 分别从第1个数到第 m 个和第 k 个,就让此时点的到人出队,然后再从1开始数。
- 点人头和出队的顺序是,两个 official 先同时点人头,然后让点的到人同时出队。
- 当两个 official 数到的是同一个人的时候,就只有这个人出队。
- 一直数到全部人出队为止。
Types
Date Structure :: Lists
Analysis
用双向循环列表模拟这个队列。
然后用两个official指针去模拟数人出队的过程。
注意在出队的时候,第一个official点到的人出队后,可能指向第二个 official 点到的人,即马上要出队的人,如果直接让第二个official点到的人出队,表示第一个official的指针会变成野指针。
Solution
// UVaOJ 133
// The Dole Queue
// by A Code Rabbit
#include <cstdio>
struct Node {
Node* pred;
int num;
Node* succ;
};
int n, k, m;
Node* head;
Node* tail;
Node* official_1;
Node* official_2;
int num_people;
void MakeList();
void CountOff(Node*& p, int num, bool is_reverse);
void Delete(Node*& p, bool is_reverse);
int main() {
while (scanf("%d%d%d", &n, &k, &m)) {
// Exit.
if (!n && !k && !m) {
break;
}
// INIT.
MakeList();
official_1 = head;
official_2 = tail;
num_people = n;
// Solving and outputs.
while (num_people) {
// Count off.
CountOff(official_1, k - 1, false);
CountOff(official_2, m - 1, true);
// Send off.
if (official_1 != official_2) {
// Outputs.
printf("%3d%3d", official_1->num, official_2->num);
if (num_people != 2) {
printf(",");
} else {
printf("\n");
}
// Delete.
Delete(official_1, false);
Delete(official_2, true);
num_people -= 2;
} else {
// Outputs.
printf("%3d", official_1->num);
if (num_people != 1) {
printf(",");
} else {
printf("\n");
}
// Delete.
official_2 = official_2->pred;
Delete(official_1, false);
num_people--;
}
}
}
return 0;
}
void MakeList() {
Node* p = new Node;
head = p;
for (int i = 0; i < n - 1; ++i) {
p->num = i + 1;
p->succ = new Node;
p->succ->pred = p;
p = p->succ;
}
tail = p;
tail->num = n;
tail->succ = head;
head->pred = tail;
}
void CountOff(Node*& p, int num, bool is_reverse) {
while (num--) {
p = is_reverse ? p->pred : p->succ;
}
}
void Delete(Node*& p, bool is_reverse) {
// Connect pred and succ.
p->pred->succ = p->succ;
p->succ->pred = p->pred;
// NOTE: Official_1 is maybe deleted when delete offcial_2.
if (is_reverse && official_2 == official_1) {
official_1 = official_1->succ;
}
// Delete.
Node* temp = is_reverse ? p->pred : p->succ;
delete p;
p = temp;
}
参考资料:无