首先,编写一个程序,对m个人进行一次计数,即排成一行。如果达到出列要求,则重新计时。最后输出出列者的编号。
#include<stdio.h> int main() { int m,n,i,k; scanf("%d%d",&m,&n); int f[m];//该数组有m个元素,代表m个人的编号 for(i=0;i<m;i++){ f[i]=i+1;//存储每个人的编号 } k=0;//计数器清0 i=0;//从第一个人开始计数 while(i<m){//因为i的取值从0到m-1 k++;从第一个人开始数 if(k==n){//满足出列条件 printf("%-5d",f[i]);//输出出列者编号 k=0;//计数器复位,重新开始+1计数,再碰到符合出列数字的人出列。 } i++;//人的编号也要持续+1,且不用重置 } return 0; }约瑟夫环是实现对m个人的循环计数,即数完第m个人后,重新回到第一个人继续计数,从而模拟m个人围成一圈的效果。
即实现约瑟夫环的关键是如何在计数完m个人后回到第1个人。即把i的条件变成i=(i+1)%m,能写出上述公式是因为要在i=m-2之前仍然是i++的效果,即余数为除数。但当i=m-1时,即最后一个人数完后,重新回到第1个人继续循环,即i变成0。但运行之后会发现,会无限循环,因为i的范围总是满足循环条件。所以要修改循环条件,最后剩余不足一个人时,即是循环结束的点。所以需要再定义一个变量是剩余人数。
同时,不要忘了把已经出列的人去掉。
#include<stdio.h> int main() { int m,n,i,k,c; scanf("%d%d",&m,&n); int f[m];//该数组有m个元素,代表m个人的编号 for(i=0;i<m;i++){ f[i]=i+1;//存储每个人的编号 } c=m; k=0;//计数器清0 i=0;//从第一个人开始计数 while(c>0){//因为i的取值从0到m-1 if(f[i]!=0){//再从下一个人开始计数时,就把已经出列的人排除即不数上。 k++; } if(k==n){ printf("%-5d",f[i]); f[i]=0;//出列的人序号清除 c--; k=0;//计数器复位,重新开始+1计数,再碰到符合出列数字的人出列。但这里唯一的问题是应该将已经出列的人排除再重新开始计数,即返回到第一个人。 } i=(i+1)%m; } return 0; }