方法一,超时:
#include <iostream>
#include <cstdio>
#include <cstring>
const int maxn=1000000;
using namespace std;
int a[maxn];
int main()
{
int n,d,i,*p;
while(scanf("%d%d",&n,&d)!=EOF&&n!=0&&d!=0)
{
p=a;
for(i=0; i<n; i++)
*(p+i)=i+1;
int j=0,k=0,m=0;
while(m<n-1)
{
if(*(p+j)!=0)k++;
if(k==d)
{
*(p+j)=0;
k=0;
m++;
}
j++;
if(j==n)j=0;
}
while(*p==0)p++;
printf("%d %d %d\n",n,d,*p);
}
return 0;
}
方法二,AC:
#include <stdio.h>
int main()
{
int n,m,s,i;
while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
{
s=0;
for(i=2; i<=n; i++)
s=(s+m)%i;
printf("%d %d %d\n",n,m,s+1);
}
return 0;
}
这里是根据那个数学公式的,for(i=2; i<=n; i++)
s=(s+m)%i;
printf("%d %d %d\n",n,m,s+1);
我们不能创造数学公式,但我们可以记住数学公式!
约瑟夫环问题:假设有N个人,报到M的人出列,问最后剩下的那个人是几号!
公式和代码如下:
int s=0;
for(i=2; i<=N; i++)
s=(s+M)%i;
printf("%d\n",s+1);
方法三,超时,但是用c语言做的:
#include <iostream>
#include <cstdio>
const int maxn=1000005;
using namespace std;
int a[maxn];
int main()
{
int n,m,sum,i,j;
while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
{
int k=0,sum=0;
for(i=0; i<n; i++)
{
a[i]=1;
}
i=0;
while(sum!=n-1)
{
if(a[i]==1)k++;
if(k==m)
{
a[i]=0;
k=0;
sum++;
}
i++;
if(i==n)i=0;
}
for(i=0; i<n; i++)
{
if(a[i]==1)
{
printf("%d %d %d\n",n,m,i+1);
break;
}
}
}
return 0;
}