约瑟夫环问题C++

约瑟夫环问题

  • 问题描述
  • 数据结构设置
  • 过程代码

问题描述

n个小朋友做成一圈,编号分别是分别为1-n,2号小朋友坐在1号小朋友顺时针方向,3号小朋友坐在2号小朋友顺时针方向……1号小朋友坐在n号小朋友顺时针方向;对于给定输入n、k,从第一位小朋友开始报数,第一位小朋友报数为1,下面的小朋友每次报数增加1,当某一位小朋友报数报到k的整数倍或者报的数的个位数为k时,该小朋友被淘汰出局。最终剩下一位小朋友,该小朋友为获胜者。
输入:n、k
输出:获胜的小朋友的编号

利用数据结构来简化问题

分析问题,需要存储的是小朋友的编号、小朋友的状态(是否淘汰出局)、小朋友的报数,环状结构则通过进行mod n实现。
因此选择结构体数组来进行数据的存储。

结构体设置

    struct Item{
        int id;
        int num;
        bool state;
        Item(int _id,int _num,bool _state=true){
            id = _id;
            num = _num;
            state = _state;
        }
    };

过程代码

经过数据结构的恰当选择,过程已经变得极为简单,只需要找出前一个报数者和后一个报数者的数组下标即可。当两个下标相等时,游戏结束。下面是完整代码:

    #include <iostream>
    #include <vector>
    using namespace std;

    struct Item{
        int id;
        int num;
        bool state;
        Item(int _id,int _num,bool _state=true){
           id = _id;
            num = _num;
            state = _state;
        }
    };


    int main(){
    int n,k;
    cin >> n >> k;
    vector<Item> loop;
    for(int i=0;i<n;i++)
        loop.push_back(Item(i+1,0));
    int pre=0,next;
    loop[0].num = 1;
    while(1){
        next = (pre+1)%n;
        while(loop[next].state!=true)
            next = (next+1)%n;
        if(next==pre){
            cout << loop[next].id;
            return 0;
        }
        else{
            loop[next].num = loop[pre].num+1;
            if(loop[next].num%k==0 || loop[next].num%10==k)
                loop[next].state=false;
            pre = next;
        }
    }
}
    原文作者:约瑟夫环问题
    原文地址: https://blog.csdn.net/qq_36630726/article/details/78707264
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞