传说约瑟夫当年活下来就是靠快速计算这个问题。
n 个人围成一圈,编号依次为 1,2,3\ldots n1,2,3…n。从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈。以此类推,直到所有的人都出列。请输出依次出圈人的编号。
输入格式
两个整数 n,m,1≤n,m≤100。
输出格式
n 个用空格分隔的整数,表示出圈人的编号。
Sample Input
6 4
Sample Output
4 2 1 3 6 5
#include<stdio.h>
int main()
{
int a[100]={0};//将所有定义的数组位置的值都为零,目的是标记它们。
int m,i,n,k=0,c,d=0;//k,i,d均为条件累加值
scanf("%d%d",&n,&m);
for(i=1;k!=n;i++)//只要找到符合条件m进行寻找n次就结束此循环,结果得出。
{
if(i>n)
{
i=1;//目的给定这n个数,这n个数的位置序号永不变。
}
if(a[i]==0)//符合标记,进入此条件语句。
{
d++;//d这个累加值是为了找到等于符合m值。
if(d==m)//d累加值达到m的时候进入此条件语句。
{
d=0;//重新初始化d,为去寻找下一次的m做准备。
a[i]=1;//每次被输出的将其标记为1,为了不进行d++计数。
printf("%d",i);//输出每次为数到m的,原始的位置序列号 。
if(k!=n)
printf(" ");
k++;//只要找到数到m的就+1,直到进行加到n就结束for循环,结果得出。
}
}
}
}
解题思路:
开始时把所有的值状态标记为0,代表这个人就在此循环的队列中。我们可以不断地循环这n个值,每当遇到在队列中的人时,计数器⏲d++(这个计数器d只有遇到a[i]==0时才能⏲+1),当d==m时,这个人出列,计数器⏲清0,状态标记为1(代表这个人出列了,不在循环的队列中),同时用来记录出列人数的k++。当k==n时,标志这n个人已经全部出列,可以退出for循环了。