首先我们了解一下约瑟夫环的历史
公元66年,约瑟夫不情愿地参与领导了犹太同胞反抗罗马统治的起义,后来起义失败,他和一些宁死不降的起义者被困于一个山洞之中。罗马将军韦斯巴芗(Vespasian)派人来劝降,他主张投降,其余的人不答应,并以死相逼。最后,约瑟夫提议,与其死在自己的手上,不如死在彼此的手上。据说,他提出用约瑟夫环方法决定生死(实际上是所有人抽签,每一轮抽到1的人把抽到2的人杀死),陆续杀死了其余被困者,最后只有他和另外一人活下来,他说服了另一个人,投降并活了下来。
下面我们来用c语言进行编程。
题目则为n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位。
#include<stdio.h>
int main()
{
int i, n, k, l;
int a[100];
k = 0;
printf("input n:\n");
scanf("%d",&n);
l = n;
for(i = 0; i < n; i++)
a[i] = i + 1; //对所有人编号
for(i = 0; ; i++) //能每次都循环
{
if(i == n) // 继续循环
i = 0;
if(a[i] != 0) //把数值相加
k++;
else continue;
if(k%3 == 0) //找出编号为3的数字
{
l--;
a[i] = 0;
}
if(l == 1)
break;
}
for(i = 0; i < n; i++)
{
if(a[i] != 0) //其余都为0
printf("%d\n",a[i]);
}
return 0;
}
k++;
else continue;
if(k%3 == 0) //找出编号为3的数字
{
l--;
a[i] = 0;
}
if(l == 1)
break;
}
for(i = 0; i < n; i++)
{
if(a[i] != 0) //其余都为0
printf("%d\n",a[i]);
}
return 0;
}
附上另一种程序
#include <stdio.h>
int main()
{
int flag[1000]={0};
int num,persons,k=0,i=0;
{
int flag[1000]={0};
int num,persons,k=0,i=0;
printf("input a number=");
scanf("%d",&num);
scanf("%d",&num);
persons = num;
while(persons != 1)
{
if(flag[i] != 1)
{
k++;
if(k == 3)
{
flag[i]==1;
persons--;
k=0;
}
}
i++;
if(i == num)
{
i = 0;
}
}
for(i = 0; i<num; i++)
{
printf("the last one is %d\n",i+1);
break;
}
return 0;
while(persons != 1)
{
if(flag[i] != 1)
{
k++;
if(k == 3)
{
flag[i]==1;
persons--;
k=0;
}
}
i++;
if(i == num)
{
i = 0;
}
}
for(i = 0; i<num; i++)
{
printf("the last one is %d\n",i+1);
break;
}
return 0;
}