约瑟夫环问题的描述为,设有编号为1,2,……,n的n(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,……,如此下去,直到所有人全部出圈为止。当任意给定n和m后,设计算法求n个人出圈的次序。

 

  解题思路: 网上给的较多的解法是循环链表和数学推导出公式的思想,但如果是一个刚接触C语言没多久的人,对循环链表的解法肯定看不懂,而数学推导的过程相信也会让很多人特别迷惑,而用数组求解还是比较容易理解的。

用数组求解的基本思想就是用一个一维数组去标识这n个人的状态,默认全为1,也就是都在圈子内,当喊道m的人出圈之后,他的标识则变为0(就是出圈了),同时报数器清0,下一个人要从1开始。在每次报数之前要判断他是否在圈子内(也就是他的标识是否为1),如果在圈子里面才会继续报数。定义一个变量记录出圈的人数, 出圈的人数等于 n-1时,则游戏结束。

注意:当m = 1的时候,如果没有if(count == m  - 1) break; 的判断,会把1到n都输出出来。

 

 1 #include<stdio.h>
 2 #define N 1000000
 3 int flag[N] = {0};
 4 int main()
 5 {
 6     int n = 0, m = 0;
 7     scanf("%d%d", &n, &m);
 8     int i = 0;
 9     int count = 0;  //记录出圈的人数
10     int num = 0;    //报数器
11     for(i = 1; i <= n; i++) {
12         flag[i] = 1;
13     }
14     while(count < n - 1) {
15         for(i = 1; i <= n; i++ ) {
16             if (1 == flag[i]) {
17                 num++;
18                 if(num == m) {
19                     printf("%d\n", i);
20                     count++;
21                     flag[i] = 0;
22                     num = 0;
23                 }
24                 if(count == n - 1) {
25                     break;
26                 }
27             }
28         
29         }
30     }
31 
32 
33     for(i = 1; i <= n; i++) {
34         if(1 == flag[i]) {
35             printf("The last one is : %d\n", i);
36         }
37     }
38 
39 
40     return 0;
41 }

 

posted on 2014-07-14 23:38  隔壁老王  阅读(6534)  评论(0编辑  收藏  举报