C++ 约瑟夫(Josephus)问题

一、题目:约瑟夫问题:n个人围成一桌,数到m的人出列

 

二、实现方法1: 每出列一个,就往前移动数组,用求余解决到尾问题

// 每出列一个,就往前移动数组
// 用求余解决到尾问题
#include <iostream>

void JosePhus(int n, int m, int start) {
    int i, *arr = new int[n]; // 动态分配数组
    int count; // 保存当前已站出来的人数
    
    for(i = 0;i < n; i++) // 初始化,把各位置号存入数组中
        arr[i] = i + 1;
    count = 1;
    start--; // 因为数组下标从0开始,所以要减1
    while(count < n) { // 当前已站出来的人数
        std::cout << arr[start] << ","; // 输出当前要站出来的人的位置号
        for(i = start; i < (n - count); i++)
            arr[i] = arr[i+1]; // 把位置号前移
        
        // start + m - 1:减1是因为该位置号的人已出列,位置号前移了一位
        // n - count: 当前剩下的人数
        start = (start + m - 1) % (n - count); // 考虑到尾了,要从头开始,所以用取余,或者用判断方法
        
        count++;
    }
    std::cout << arr[0] << "\n";
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int n, m, start; // n:人数  m:数到多少出列  start:开始位置
    
    std::cout << "请输入n,m,start:\n";
    while(std::cin >> n >> m >> start) {
        JosePhus(n, m, start); // 调用解决约瑟夫问题的函数
        std::cout << "请输入n,m,start:\n";
    }
    return 0;
}

运行结果:

、实现方法2不移动数组:将数组该位置已出列的设为零

//  不移动数组:将数组该位置已出列的设为零
//  总结:(1)移动数组:将位置号前移,会耗费很多时间
//       (2)不移动数组:当剩下的人数较少时,找不为0的会耗费很多时间
#include <iostream>

void JosePhus(int n, int m, int start) {
    int i, *arr = new int[n]; // 动态分配数组
    int count; // 保存当前已站出来的人数
    
    for(i = 0;i < n; i++) // 初始化,把各位置号存入数组中
        arr[i] = i + 1;
    count = 1;
    start--; // 因为数组下标从0开始,所以要减1
    int mCount; // 记录数了多少
    while(count < n) { // 当前已站出来的人数
        std::cout << arr[start] << ","; // 输出当前要站出来的人的位置号
        arr[start] = 0; // 将当前要出列的位置号设为0
        mCount = 0;
        // 从start开始数
        while(mCount < m) {
            if(start == 7) // 条件判断:是否已到数组尾
                start = 0;
            else
                start++; // 往后移
            if(arr[start] > 0) { // 不为0,还没出列
                mCount++;
            }
        }
        count++;
    }
    for(i = 0; i < n; i++) { // 输出最后一个人
        if(arr[i] > 0) {
            std::cout << arr[i] << "\n";
            break;
        }
    }
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int n, m, start; // n:人数  m:数到多少出列  start:开始位置
    
    std::cout << "请输入n,m,start:\n";
    while(std::cin >> n >> m >> start) {
        JosePhus(n, m, start); // 调用解决约瑟夫问题的函数
        std::cout << "请输入n,m,start:\n";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/chuanzhouxiao/article/details/85493718