约瑟夫问题(也叫丢手帕问题)不涉及很多算法,但却是一个很好的逻辑训练题!也是ACM训练OJ上的一道题(http://acm.nyist.net/JudgeOnline/problem.php?pid=278)。
我用数组模拟做了一下:
//丢手帕问题 约瑟夫问题
#include<stdio.h>
#include<string.h>
int main()
{
int i,n,n1,begin,begin1,num,num1;
scanf("%d%d%d",&n,&begin,&num);
n1=n;//人数
begin1=begin-1;//开始位置,注意数组下标和实际位置的差别
num1=num;//计数
int a[n];
memset(a,0,sizeof(int)*n);
printf("剩余个数\t位置\n");
while(n1>=1)
{
i=begin1;//新的开始位置
num1=0;//重置计数
while(1)//找到要删除的位置
{
if(a[i]==0)
num1++;
if(num1==num)//这样跳出时正好是要出列的位置
break;
i=(i+1)%n;//循环
}
a[i]=1;//置1 出列
while(a[i]==1)//找下一个开始的位置
i=(i+1)%n;//注意死循环
begin1=i;
n1--;
printf("%d\t\t",n1);
for(i=0;i<n;i++)
{
if(a[i]==0)
printf("%d ",i+1);
}
printf("\n");
if(n1==1)
{
printf("\n%d\n",begin1+1);
break;//最后剩下一个 结束
}
}
return 0;
}
还有人发现了他们之间的规律,用递推做的(默认开始是1):
#include <stdio.h>
int main()
{
int t, m, n,i, f;
scanf("%d", &t);
while(t-- && scanf("%d%d", &n, &m))
{
f = 0;
for(i = 2; i <= n; ++i)
f = (f + m) % i;
printf("%d\n", f + 1);
}
return 0;
}
这个我没有仔细研究。