约瑟夫问题-c基础第一课

来源:互联网 发布:淘宝招商是做什么的 编辑:程序博客网 时间:2024/06/07 12:14

约瑟夫问题

约瑟夫问题一般有两种解决方法,一种数组,一种链表,本次采用数组方式说明解决。

规则:

n个人围成一个圈,每个人分别标注为12...n,要求从1号从1开始报数,报到k的人出圈,接着下一个人又从1开始报数,如此循环,直到只剩最后一个人时,该人即为胜利者。例如当n=10,k=4时,依次出列的人分别为48273109165,则5号位置的人为胜利者。给定n个人,请你编程计算出最后胜利者标号数

 

步骤:

(1) 为了程序可扩展性,数组大小定义大一些,然后根据用户输入来确定参加游戏的人数和要杀掉的人的位置数。

(2) 当循环超过用户定义的游戏人数时定义一个简单算法重新开始。

(3) 如果这个人没死就报数。

(4) 如果报的数是要杀死的位置数但没有死n-1个人则标志死亡人数,然后游戏继续。

(5) 如果报的数是要杀死的位置数但是已经死了n-1个,即只剩余该人一人时就打印该人的位置数。

 

流程图:

 略。

代码:

#include int main(){    int n, k;    int i;    int a[1001];    int dead = 0;                              //表示已经死了多少人      int num = 0;                             //num模拟没有被杀的人的喊数     printf("n个人围成一个圈,每个人分别标注为1、2、...、n,要求从1号从1开始报数,报到k的人出圈,接着下一个人又从1开始报数,如此循环,直到只剩最后一个人时,该人即为胜利者。例如当n=10,k=4时,依次出列的人分别为4、8、2、7、3、10,9、1、6、5,则5号位置的人为胜利者。给定n个人,请你编程计算出最后胜利者标号数。(要求用单循环链表完成。)第一行为人数n;第二行为报数k:\n");scanf("%d%d", &n, &k);     for (i = 1; i <= n; i++)             //开始时每个人都可以报数,为了能得到最后一个人的编号,我们让初始值为i下标      {        a[i] = i;    }    for (i = 1;; i++)    {        if (i > n)        {            i = i%n;                     //如果大于总人数,我们就从头开始          }         if (a[i] > 0)                        //如果当前这个人没有死,就报数              num++;         if (k == num && dead != n - 1)          //如果当前这个人报的数等于k并且没有已经死亡n-1个人          {            num = 0;            a[i] = 0;            dead++;        }        else if (k == num && dead == n - 1)  //如果这个人报数等于k,并且已经死了n-1个人,说明当前这个人就是最后的一个活着的了。。          {            printf("%d", a[i]);            break;        }    }        return 0;}

结果: