【UVaOJ】133 - The Dole Queue


 The Dole Queue 

In a serious attempt to downsize (reduce) the dole queue, The NewNational Green Labour Rhinoceros Party has decided on the followingstrategy. Every day all dole applicants will be placed in a largecircle, facing inwards. Someone is arbitrarily chosen as number 1,and the rest are numbered counter-clockwise up to N (who will bestanding on 1's left). Starting from 1 and moving counter-clockwise,one labour official counts off k applicants, while another officialstarts from N and moves clockwise, counting m applicants. The two whoare chosen are then sent off for retraining; if both officials pickthe same person she (he) is sent off to become a politician. Eachofficial then starts counting again at the next available person andthe process continues until no-one is left. Note that the two victims(sorry, trainees) leave the ring simultaneously, so it is possible forone official to count a person already selected by the other official.

Input

Write a program that will successively read in (in that order) thethree numbers (N, k and m; k, m > 0, 0 < N < 20) and determinethe order in which the applicants are sent off for retraining. Eachset of three numbers will be on a separate line and the end of datawill be signalled by three zeroes (0 0 0).

Output

For each triplet, output a single line of numbers specifying the orderin which people are chosen. Each number should be in a field of 3characters. For pairs of numbers list the person chosen by thecounter-clockwise official first. Separate successive pairs (orsingletons) by commas (but there should not be a trailing comma).

Sample input

10 4 3
0 0 0

Sample output

4 8, 9 5, 3 1, 2 6, 10, 7

where represents a space.

思路:

      也是一道很简单的题,使用环形链表即可。需要注意的地方是一些边界条件,还有就是某个official的所在位置不能是即将被删除的位置。


C++代码实现:

#include <cstdio>
#include <list>

using namespace std;

int main(int argc, char*argv[])
{
    int sz;
    int k, m, n;
    list<int> appl;
    list<int>::iterator ccl; // 逆时针迭代器
    list<int>::iterator cl; // 顺时针

    while (scanf("%d%d%d", &n, &k, &m) != EOF && n && k && m) {
        appl.clear();
        // 初始化
        for (int i = 1; i <= n; ++i) {
            appl.push_back(i);
        }
        ccl = appl.begin();
        cl = --appl.end();

        while ((sz = appl.size()) > 1) {
            for(int i = 1; i < k; ++i) {
                if (++ccl == appl.end()) { ccl = appl.begin(); }
            }
            printf("%3d", *ccl);

            for (int i = 1; i < m; ++i) {
                if (cl == appl.begin()) { cl = appl.end(); }
                --cl;
            }

            if (cl != ccl) {
                printf("%3d", *cl);

                // 备份将被删除的节点位置
                list<int>::iterator tmp1 = cl;
                list<int>::iterator tmp2 = ccl;

                do {
                    if (cl == appl.begin()) { cl = appl.end(); }
                    --cl;
                }while (cl == tmp2); // 不能指向即将被删除的节点

                do {
                    if (++ccl == appl.end()) { ccl = appl.begin(); }
                }while (ccl == tmp1); // 不能指向即将被删除的节点

                appl.erase(tmp1);
                appl.erase(tmp2);
            } else {
                list<int>::iterator tmp = ccl;
                ccl = ++ccl == appl.end() ? appl.begin() : ccl;
                cl = cl == appl.begin() ? --appl.end() : --cl;

                appl.erase(tmp);
            }


            if (!appl.empty()) {
                printf(",");
            }
        }

        if (!appl.empty()) { printf("%3d", appl.back()); }
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(链表,133,UvaOJ)