3119 - 约瑟夫问题2——oj

3119 - 约瑟夫问题2

题目描述

约瑟夫问题:有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
7

标签
链表
错误代码

#include<bits/stdc++.h>
using namespace std;
int main() {
    int n=1,m=1,a[10000],b[10000],t,k=n,i=1,head=0;
    while(1) {
        cin>>n>>m;
        if(n==0&&m==0)
            break;
        for(i=0; i<n-1; i++) {
            a[i]=i+1;
            b[i]=i+1;
        }
        a[n]=n;
        b[n]=0;
        head=0;
        k=head;
        i=1;
        while(n>1) {
            i++;
            if(i==m) {
                t=b[k];
                b[k]=b[t];
                if(t==head)
                    head=b[k];
                i=1;
                n--;
            }
            k=b[k];
        }
        cout<<a[head]<<endl;
    }
    return 0;
}

有哪个好人能帮助我一下!


#include<iostream>  
using namespace std;  
  
int josephus(int n, int m) {  
    if (n == 1) return 0;  
    else return (josephus(n - 1, m) + m) % n;  
}  
  
int main() {  
    int n, m;  
    cout << "Enter the total number of monkeys: ";  
    cin >> n;  
    cout << "Enter the number m: ";  
    cin >> m;  
  
    cout << "The monkey king is: " << josephus(n, m) + 1 << endl;  
    return 0;  
}

这个程序首先定义了一个名为 josephus 的函数,该函数通过递归实现约瑟夫环的解决方法。然后在 main 函数中,程序接收用户输入的猴子总数 n 和数到 m 的猴子退出的规则。最后,程序输出猴王的编号。

注意,由于编号从1开始,因此在输出猴王编号时,我们需要将结果加1。

【以下回答由 GPT 生成】

优化后的问题:

问题标题: 如何优化3119-约瑟夫问题2的解法?

问题描述: 3119 - 约瑟夫问题2 是一个关于约瑟夫问题的问题。约瑟夫问题是这样的:有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 7

提示: 请帮我优化以下代码

#include<bits/stdc++.h>
using namespace std;
int main() {
    int n=1,m=1,a[10000],b[10000],t,k=n,i=1,head=0;
    while(1) {
        cin>>n>>m;
        if(n==0 && m==0)
            break;
        for(i=0; i<n-1; i++) {
            a[i]=i+1;
            b[i]=i+1;
        }
        a[n]=n;
        b[n]=0;
        head=0;
        k=head;
        i=1;
        while(n>1) {
            i++;
            if(i==m) {
                t=b[k];
                b[k]=b[t];
                if(t==head)
                    head=b[k];
                i=1;
                n--;
            }
            k=b[k];
        }
        cout<<a[head]<<endl;
    }
    return 0;
}

优化提示: - 尽量避免使用全局变量,使用局部变量更加安全可控。 - 将问题划分为更小的函数,提高代码的可读性和可维护性。 - 使用更具意义的变量名,增加代码的可读性。 - 使用合适的数据结构,减少代码的复杂性。

希望能够对你有所帮助!

优化解决方案:

#include <iostream>
#include <vector>

using namespace std;

int josephus(int n, int m) {
    vector<int> monkeys;
    for (int i = 1; i <= n; i++) {
        monkeys.push_back(i);
    }

    int index = 0;
    while (monkeys.size() > 1) {
        index = (index + m - 1) % monkeys.size();
        monkeys.erase(monkeys.begin() + index);
    }

    return monkeys[0];
}

int main() {
    int n, m;
    while (cin >> n >> m) {
        if (n == 0 && m == 0) {
            break;
        }
        cout << josephus(n, m) << endl;
    }
    return 0;
}

优化解决方案的思路如下: - 使用vector代替数组,动态管理猴子的编号,减少内存消耗; - 使用循环计算需要删除的猴子的索引,而不是遍历整个数组删除,减少时间复杂度; - 代码逻辑更加简洁明了,易于理解和维护。

请注意,优化后的代码并不是原始代码的修改,而是对原始代码进行了重写。这种问题的优化存在多种方法和思路,以上仅提供一种示例。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^