约瑟夫问题
题目描述
有M个人,其编号分别为1-M。这M个人按顺序排成一个圈。现在给定一个数N,从第一个人开始依次报数,数到N的人出列,然后又从下一个人开始又从1开始依次报数,数到N的人又出列...如此循环,直到最后一个人出列为止。
输入
输入只有一行,包括2个整数M(8 <= M <= 15 ),N( 5 <= N <= 32767 )。之间用一个空格分开。
输出
输出M行,每行一个整数。
***样例***
输入
8 5
输出
5
2
8
7
1
4
6
3
代码如下:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i,j,k,m,n,a[20];
scanf("%d%d",&m,&n);
for(i=1;i<=m;i++)
{
a[i]=i;//每一个元素对应一个位置
}
k=1;
do{
k=(k+n-1)%m;//因为每一次都要从自身位置开始查起,所以要进行减1操作。
if(k==0)//因为当其为0时说明了该位置是人数的整数倍,所以要输出最后一个
printf("%d\n",a[m]),
k++;//是因为没有0这个位置,当其为0时说明其在最后一个位置,所以下一次查的时候需要从1开始,故进行加1操作
else
{
printf("%d\n",a[k]);
for(i=k;i<m;i++)
{
a[i]=a[i+1];//当k位置的人出列后,把后面的元素都要前进一位。
}
}
}while(--m);//先减1在判断,直到人数为0为止。
return 0;
}