约瑟夫问题
描述
约瑟夫问题是一个非常经典的问题,它的问题描述是:有 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;
}