T、DZ 2023-06-06 17:29 采纳率: 45.5%
浏览 27

约瑟夫环时间超限问题(语言-c++)

题目描述
n个人排成一圈,按顺时针方向依次编号1,2,3…n。从编号为1的人开始顺时针报数,报到m的人退出圈子。这样不断循环下去,圈子里的人将不断减少。最终一定会剩下一个人。试问最后剩下的人的编号。

输入
不超过1000组数据。

每组数据一行,每行两个正整数,代表人数n (1 <= n < 231)和m(1<=m<=1000)。

输出
每组输入数据输出一行, 仅包含一个整数,代表最后剩下的人的编号。

样例
7 2
2 2
7
1
为什么代码会时间超限啊,这个效率不是很高了吗?

#include <iostream>

using namespace std;

long long found(long long n,long long m)
{
    long long answer=1,i,a;
    for(i=2;i<=n;i++)
    {
        if(i>answer+m)
        {
            a=(i-answer)/m;
            if(a>n-i)
                a=n-i;
            i+=a;
            answer+=a*m;
        }
        answer=(answer+m-1)%i+1;
    }
    printf("%lld\n",answer);
    return 0;
}

int main()
{
    long long n,m;
    while(scanf("%lld%lld",&n,&m)!=EOF)
    {
        if(n<2)
            printf("1\n");
        else
            found(n,m);
    }
    return 0;
}
  • 写回答

2条回答 默认 最新

  • bluetata 云计算领域优质创作者 2023-06-07 10:33
    关注

    你这个是"约瑟夫环问题",如果全使用循环会比较慢
    剩下的人的编号可以通过以下公式计算可以换称这个
    f(n, m) = (f(n-1, m) + m) % n
    下面的代码可以自行运行测试一下

    #include <iostream>
    using namespace std;
    
    int findLastPerson(int n, int m) {
        int lastPerson = 0;
        for (int i = 2; i <= n; i++) {
            lastPerson = (lastPerson + m) % i;
        }
        return lastPerson + 1;
    }
    
    int main() {
        int n, m;
        while (cin >> n >> m) {
            cout << findLastPerson(n, m) << endl;
        }
        return 0;
    }
    
    评论

报告相同问题?

问题事件

  • 创建了问题 6月6日

悬赏问题

  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?