约瑟夫问题

描述

约瑟夫问题是一个非常经典的问题,它的问题描述是:有 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;
}
posted @ 2017-05-18 23:01  让你一生残梦  阅读(128)  评论(0编辑  收藏  举报