约瑟夫问题(猴子选大王 C++题解)

说明

约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入格式

每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是: 0 0

输出格式

对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号

样例

输入数据 

6 2
12 4
8 3
0 0

输出数据

5
1

今天来解决这一道题,经典的约瑟夫问题

老规矩,直接上码,边看边讲

//代码不十分复杂,使用到了队列(队列处理约瑟夫是真的很方便)
#include <bits/stdc++.h>
using namespace std;
int main(){
    //首先定义一个队列
    queue <int> q;

    //定义两个数组,分别存储猴子数量和出局序号
    int nn[500], mm[500];

    //变量len储存上面数组的长度,biao表示当前下标,下面有体现
    int len= 0,biao = 0;

    //因为输入数量无限制,直到0 0才结束,所以设置结束判断
    while(true){
        cin >> nn[biao] >> mm[biao];
        if (nn[biao] == 0 && mm[biao] == 0) break;//结束判断
        len++;
        biao++;
    }//每次输入都要使长度和下标++
    
    //开始循环
    for (int i = 0; i< len; i++){
        //将数据存入队列
        for (int j = 1; j <= nn[i];j++){
            q.push(j);
        }
        
        //记录出局序号;当出局序号达到要求时,将第一个人出局;当还剩一人时停止转圈,立刻输出
        int count = 0;
        while(q.size() > 1){
            count++;
            if (count == mm[i]){
                q.pop();
                count = 0;
            }
            else{
                int t = q.front();
                q.pop();
                q.push(t);
            }
        }
        cout << q.front() << endl;
        q.pop();//最后要记得将队列清空(只剩下了一只猴王,清一次就可以)
    }
    
    return 0;
}

搞定了,测试结果完全正确

不过我仍然坚信还有改进的空间,如果有更好的建议可以留下您宝贵的评论

感谢您的指点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值