约瑟夫问题

描述

约瑟夫问题是一个非常经典的问题,它的问题描述是:有 n 个人围成一圈,从第 1 个人开始,每次按顺时针方向向后选择第 m 个人,并将这个人出列。那么你能高效的算出出列的顺序吗?

输入

输入数据有多组,每组输入数据为一行,两个正整数 n和m (1<=n,m<=30000)

输出

每组输出只有一行,表示出列的顺序。每两个数字之间用一个空格分开。

样例输入

4 2

5 3

样例输出

2 4 3 1

3 1 5 2 4

代码如下:

#include<stdio.h>
int f[30000];
int main()
{   
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
    memset(f,0,sizeof(f));
    int sum=0;
    int j=1;
    int ff=0;
    for(int i=1;i<=n;i++)
    {
         sum=0;
         for(;;)
         {
             if(f[j]==0)
               sum++;
             if(sum==m)
               {
               f[j]=1;
               if(ff++!=0)
                printf(" ");
                cout<<j;
               break;    
               }
            j++; 
             if(j==n+1)
               j=1;
         }
    }
    cout<<endl;
}
return 0;
}

代码超时间了,对于时间短的就可以了。但是人数达到1e6以上的时候,就会爆了。
所以我们要去优化代码。

代码如下:
来自于:http://blog.csdn.net/kangroger/article/details/39254619

#include<iostream>
using namespace std;
int main()
{
  int N;//人的总个数
  int M;//间隔多少个人

  cin>>N;
  cin>>M;
  int result=0;//N=1情况
for (int i=2; i<=N; i++)
{
    result=(result+M)%i;
}
   cout<<"最后自杀的人是:"<<result+1<<endl;//result要加1
   return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值