【问题描述】
17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:
15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余
的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人
开始依次报数,每数到第九个人就将他扔入大海,此循环进行直到仅余
15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
【问题分析】
从问题的描述中可以得知:程序最终应该输出非教徒在排序中所站的位置。则需考虑:
在这个程序中,处理的主要数据是非教徒是否跳入海中。因而启发我们用0和1表示人的状态:0表示还在船上;1表示已经跳入海中。则用int
作为数据类型。又由于需要筛选出跳入海中的非教徒,所以需要将这30个人组织在一起形成批量数据,以便共同参与及筛选。此处则可选用一维数组完成。
【关键问题】
对于计数,我们可以从第一个还未扔下海的人开始进行计数,每数到9时,将该元素的值改为1,表示该人已经被扔下海。接着重置number,再数到9。这样循环直到扔下海15个人为止。
【代码如下】
#include<stdio.h>
void main(){
int person[30] = {0};
//表示30个人都还在船上
int i=0;
int number=0; //表示現在數到几
int counter=0; //統計目前跳下去幾人
do{
/* i%30:表示計數,i最終不會超過30*/
if(person[i%30] == 0) //等於0表示第i個位置的人目前在船上
number++; //在船上表示計數有效
/* 本次數到第9個人 */
if(number == 9){
person[i%30] = 1; //丟下船
counter++; //丟下船的人的總數加一
number = 0; //重新開始數
}
i++; //增量
}while(counter<15); //停止條件為已經丟下去十五人
printf("需要跳下去的人是:");
/* 輸出 */
for(i=0;i<30;i++){
if(person[i] == 1)
printf("%d\t",i+1);
}
}
【运行结果】