问题描述:
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; }
原文地址:http://blog.csdn.net/mingyong_blog/article/details/40953137