[面试] 面向对象的约瑟夫环问题的通法 [ C++实现 ] [为夏逸轩师弟作]

说明 :有两个类,Kid 和 KidCircle,
类Kid代表王子,就是王子类,这个类里面有一个王子编号id, int类型的, 还有两个 王子kid指针 left 和  right ,因为王子们要围成一个圈子嘛,所以left,right分别代表该王子的左手边的人和右手边的人!  类KidCircle就是“王子圈”类,类中count记录该“王子圈”里面有多少个人,first,last分别指向第一个王子 和 最后一个王子!KidCircle(int);构造方法是用来初始化 此时的王子圈的,参数int表示圈子中有多少人,add()是向圈中增加王子,del()是删除圈中的王子!
#include <iostream>
#include <cstring>
#include <cstdio>
#define BUG cout << "here\n";
using namespace std;

class Kid {
public :
    int id;
    Kid* left;
    Kid* right;
};
class KidCircle {
public :
    int count;
    Kid *first, *last;
public :
    KidCircle(int);
    void add();
    void del(Kid*&);
};
KidCircle::KidCircle(int n) : count(0) {
    for(int i = 1; i <= n; i++) {
        add();
    }
}
void KidCircle::add() {
    Kid *k = new Kid();
    count++;
    k->id = count;
    if(count <= 1) {
        first = k;
        k->left = k;
        k->right = k;
        last = k;
    }
    else {
        last->right = k;
        k->left = last;
        k->right = first;
        first->left = k;
        last = k;
    }
}
void KidCircle::del(Kid*& k) {
    if(count <= 0) {
        return;
    }
    else if (count == 1) {
        first = last = NULL;
    }
    else {
        if(k->left)
            k->left->right = k->right;
        if(k->right)
            k->right->left = k->left;

        if(k == first) {
            first = k->right;
        }
        else if(k == last) {
            last = k->left;
        }
    }
    count--;
}
int main() {
    int T, n, m;
    cin >> T;
    while(T--) {
        cin >> n >> m;
        KidCircle *kc = new KidCircle(n); /// n 个王子的围成的 圈

        int countNum = 0;
        Kid *k = kc->first; /// 王子

        while(kc->count > 1) { /// 圈子中剩下的王子大于 1
            countNum++;
            if(countNum == m) {
                countNum = 0;
                cout << k->id << ' ';
                kc->del(k);
            }
            k = k->right;
        }
        cout << k->id << endl;
    }
    return 0;
}

posted @ 2013-01-29 21:13  小尼人00  阅读(355)  评论(0编辑  收藏  举报