首页 > 代码库 > 【刷题小记】用数组模拟约瑟夫环

【刷题小记】用数组模拟约瑟夫环

   问题描述:

       n 个人围城一圈,第1个人从1开始报数,报数到m的人出列,然后从下一个人开始又从1开始报数,重复游戏n-1次,每次淘汰1人,最后剩下的人就是胜利者。

   实心方法:

          这是约瑟夫环问题,可以用链表实现,我在这里用数组实现,具体分析如下:

          用到变量:以n=8,m=4为例说明

           r:控制循环次数

           i:用于记录每次出列的人位置,从1变化到8再到1

           j:用于控制报数,从1变化到4,在到1....

  

                                  图1

  

                                     图2

    

                                     图3

     

                                   图4

     

                                         图5

      

                                           图6

       

                                      图7

       

                                    图8

    注意的地方:

   1)模拟报数过程,从1开始报数,达到4后,又从1开始,因此要对4进行取摸运算,但是j%4的范围是从0~3,希望的范围是1~4,所以j的正确表达式是j=j%4+1;

          2)   变量i表示报数是由哪个人报出的,每次继续报数应该对8取摸后加1,即 i=i%8+1;

 3)  在报数的过程中,要跳过已经出列的人,实现将数组的值设定为其下标,每出列一个位置,将改元素的位置为0,如果某个位置对应的数组元素值为0,就跳过改位置。 7轮过后数组元素值不为0的位置就是winner


#include <stdio.h>
#include <stdlib.h>

int main()
{
	const int n=8;
    const int m=4;
    int a[9]={0,1,2,3,4,5,6,7,8};
    int r=1;
    int i,j;
    
    for(i=1,j=1;r<=7;)
    {
		while(a[i]==0)
			i=i%n+1;
         if(j%m==0)
         {
			printf("a[%d]=%d\n",i,a[i]);
            a[i]=0;
            j=0;
            r++;
         }
         i=i%n+1;
         j=j%m+1;
    }
    for(i=0;i<n;i++)
    {
		if(a[i+1]!=0)
			printf("the last winner is :%d\n",a[i+1]);
    }
	return 0;
}



【刷题小记】用数组模拟约瑟夫环