经典智力推算题中“11个教徒”的问题:
有一次,一艘船在海上遇到风暴。为了减轻船的重量,摆在25名乘客面前的选择是把一部分人抛到海里。这样,船和剩下的人也许还能得救。谁也不愿意自动跳入海中。乘客里有11个教徒,其中一个想出了一个主意。他让所有的25人坐成一圈,然后依次报数“1、2、3”,规定报到“3”的人就被抛到海里。最后报数的结果有14人被抛下海。剩下的是这11个教徒。那么,他是如何安排这些剩余者的位置的?
由此变形出来的题目:
A)25个人排成一列,依次报数“1、2、3”,规定报到“3”的人就要出列。每轮都从队头的人开始报数,剩余到2人以后报数停止。问出列的人的编号依次是什么?
这题比较简单,直接贴代码了:
<html>
<head>
</head>
<body>
<script language="javascript">
var p=new Array();
var q=new Array();
var h,i,j,k=25,l=0;// k为队列初始长度
var count=1,bh=3;
for(i=1;i<=k;i++)
{
p[i]=i; //值与下标匹配
//alert(p[i]);
}
function whoIsOut(j){
if(p[j]>0)
{
if(j%bh==0) //如果报号到逢3的
{
alert('第'+count+'轮出列的人标号为'+p[j]);
p[j]=0; //出列,记为0
}
else
{
l=l+1; // //记录所有不为0的个数
q[l]=p[j]; //保存对应的下标
}
j=j+1;
if((j==k+1)&&(k>=bh))
{
for(j=1;j<l+1;j++)
{ p[j]=q[j];
}
count=count+1;
j=1;
k=l;
l=0;
}
whoIsOut(j);
}
}
whoIsOut(1);
</script>
</body>
</html>
B)25个人排成一圈,依次报数“1、2、3”,规定报到“3”的人就要出列。出列后继续顺延报数,剩余到2人以后报数停止。问出列的人的编号依次是什么?
思路:如果当队列长度刚好是3的倍数的时候,即退化为上面的习题,每次都从队头开始报数了;所以考虑队列长度不是3的倍数,则可以算出队列长度比3的倍数还多余几个,将多余的几个按原顺序调到队头,加上原来队头的顺序元素,即又可退化为上面的习题,从队头开始报数。一直递归下去,即可算出出列的人的编号。
代码:
<html>
<head>
</head>
<body>
<script language="javascript">
var p=new Array(); //待出列的队伍
var q=new Array(); //保留下一轮要出列的队伍
var h,i,j,k=25,l=0,m=1; //k:队长;h:原队长多了多少,多余的部分就要调到队头去重新循环;i:赋初值时用的循环变量;j:本轮待比较的元素的下标;l:记录本轮出队后剩余的未出队的人的个数;m:记录下一轮要进入循环时的数组的下标
var count=1,bh=3; //count:记录出队的轮次;bh:逢几就出列的监视哨;
for(i=1;i<=k;i++)
{
p[i]=i; //值与下标匹配
}
function whoIsOut(j){
if((p[j]>0)&&(k>=bh)) //没有出列的且队长还允许出列的
{
if(j%bh==0) //如果报号到逢bh的
{
alert('第'+count+'轮出列的人标号为'+p[j]);
p[j]=0; //出列,记为0
}
else
{
l=l+1; // //记录所有不为0的个数
q[l]=p[j]; //保存对应的下标
}
j=j+1;
if((j==k+1)&&(k>=bh)) //j到了队尾了且队长要大于监视哨定义的长度(否则不够出列)
{
m=1;
if(k%bh>0) //原队长出列后是否有多余元素
{
h=k%bh; //多余元素的个数
if(h>0) //说明要将多余的个数需要调到前面去
{
for(;h>0;h--)
{
p[m]=q[l-h+1];
m=m+1;
}
}
}
//alert('m:'+m);
for(j=m;j<l+m+1;j++)
{
p[j]=q[j-m+1]; //加入其余的剩余元素,形成下一轮出队的数组
}
count=count+1; //出队完成一轮,开始累加
j=1; //计数器还原
k=l; //队长退化为非0个数
l=0; //非零数重新计数
}
whoIsOut(j); //递归
}
}
whoIsOut(1); //调用看效果
</script>
</body>
</html>
限于时间和技术,没有做成可以输入队列长度和逢几报号,并通过按钮来打印结果的形式。这两题算是很简单的题目,但是我做了很久,做完以后才知道原来挺简单的,呵呵。以此纪念我笨笨的算法,因为我在一点一滴地努力进步。。。。。。