UVaOJ 133 - The Dole Queue

——by A Code Rabbit


Description

  • 有 n 个人(从0到 n – 1)排成一队,队头和队尾相连,变成一个圈。
  • 然后有两个 official ,一个从队头开始顺序点人头,一个从队尾开始逆序点人头。
  • 分别从第1个数到第 m 个和第 k 个,就让此时点的到人出队,然后再从1开始数。
  • 点人头和出队的顺序是,两个 official 先同时点人头,然后让点的到人同时出队。
  • 当两个 official 数到的是同一个人的时候,就只有这个人出队。
  • 一直数到全部人出队为止。
输入队列人数 n,和两个official分别报的数 m, k ,输出出队的顺序。


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;
}



下载pdf

参考资料:无

你可能感兴趣的:(UVaOJ 133 - The Dole Queue)