T、DZ 2023-06-06 17:29 采纳率: 83.3%
浏览 28
已结题

约瑟夫环时间超限问题(语言-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条回答 默认 最新

  • 失棉的羊 . 2023-06-15 01:17
    关注

    该代码实现了约瑟夫环问题,即给定n个人排成一圈,按顺时针方向依次编号1,2,3...n,从编号为1的人开始顺时针报数,报到m的人退出圈子,然后继续从下一个人开始报数,直到最后只剩下一个人,求最后剩下的人的编号。

    代码中的found函数用于计算最后剩下的人的编号。在循环中,通过判断i是否大于answer+m来确定是否需要跳过一些人,从而提高效率。如果需要跳过的人数a大于n-i,则将a设为n-i,以确保不会越界。然后更新i和answer的值。最后,根据计算得到的answer输出结果。

    在主函数中,通过循环读取输入的数据,如果n小于2,则直接输出1,否则调用found函数计算结果。

    然而,该代码的时间复杂度较高,可能导致在输入规模较大时出现时间超限的问题。需要优化算法以提高效率。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 6月12日
  • 已采纳回答 6月4日
  • 创建了问题 6月6日

悬赏问题

  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!