问题描述:
. 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位?
网上的递推公式
f[1]=0;
f[i]=(f[i-1]+m)%i; (i>1)
我看了很长时间才看懂,所以把我的想法发出来。
比如说n为7,人分别为1 2 3 4 5 6 7
接下来为退出的过程
1204567 3退出 记为0
4567120 从4开始从新报数
4507120 6退出 记为0
7124500 从7开始从新报数
7104500 2退出 记为0
4571000 从4开始从新报数
4501000 7退出 记为0
1450000 从1开始从新报数
1400000 5退出 记为0
0400000 1退出 最后留下4
c代码实现如下
#include <stdio.h>
#include <stdlib.h>
int movethree(int a[],int n,int m)
{
int b[n],i,j;
if(a[2]==0)
return a[1];
else
{
for(i=0,j=0; j<n-m; i++,j++)
{
if(i==2)
{
a[i]=0;
}
b[j]=a[i+3];
}
b[n-3-m]=a[0];
b[n-2-m]=a[1];
b[n-1-m]=a[2];
m++;
}
return movethree(b,n,m);
}
int main(void)
{
int n,i,a[100];
scanf("%d",&n);
for(i=0; i<n; i++)
{
a[i]=i+1;
}
printf("%d\n",movethree(a,n,0));
return 0;
}
比较简单的代码如下
#include <stdio.h>
#include <stdlib.h>
int threeout(int n)
{
int i, r = 0;
for (i = 2; i <= n; i++)
{
r = (r + 3) % i;
}
return r+1;
}
int main(void)
{
int n;
scanf("%d",&n);
printf("%d\n",threeout(n));
return 0;
}
这个问题我想的还不够,如果有更好的理解,希望讨论一下。