这是我用Java写的另一个算法:////////////////////////////////////////////////////////////////////////////////////////////////
//  题目:有13个小球,其中有且只有一个是次品,这里所指的次品是说它的重量与其它的小球不同。现  //
//        在给你一架天平,要求最多只能称量三次就得要把那个次品找出来。注意,天平不能告诉你球  //
//   的绝对重量, 但可以知道天平的状态--哪一边的重量大。                                 //
//  来由:2005/04/30下午在某公司面试时给我出的一道题(当时没要求写代码)  //
//  作者:高继福                                          时间:2005/04/30晚   05/07上午修改  //
//////////////////////////////////////////////////////////////////////////////////////////////////描述小球类
class Ball 
{
//记录小球的编号
private int index = 0; //小球的重量属性:其值为0时表示是一个标准球;为-1时表示是一个比标准球的重量小的次品,
//    为+1时表示的是一个比标准球的重量大的次品
private int weight = 0; //设置小球的编号
public void setIndex(int index)
{
this.index = index;
} //取得小球的编号
public int getIndex()
{
return this.index;
} //设置小球的重量
public void setWeight(int weight)
{
this.weight = weight;
} //取得小球的重量
public int getWeight()
{
return this.weight;
}
}//描述天平类
class Balance
{
//天平的状态属性:其值为0时表示两边平衡;为-1时表示左边轻,为+1时表示的是左边重
private int state = 0; //设置天平的状态
public void setState(int state)
{
this.state = state;
} //取得天平的状态
public int getState()
{
return this.state;
} //传进两个小球做参数,用天平称量后,重置天平状态的属性
public void beginWeigh(Ball b1,Ball b2)
{
//比较后给天平进行重置
if(b1.getWeight() < b2.getWeight())
this.setState(-1);
else if(b1.getWeight() > b2.getWeight())
this.setState(+1);
else
this.setState(0);
} //传进两个小球类数组参数,用天平称量后,重置天平状态的属性
public void beginWeigh(Ball[] array_b1,Ball[] array_b2)
{
//每个数组的总长度
int array_b1_length = array_b1.length;
int array_b2_length = array_b2.length; //每个数组中小球的总重量
int array_b1_weight_total = 0;
int array_b2_weight_total = 0; //计算天平左边小球的总重量
for(int i=0;i<array_b1_length;i++)
{
array_b1_weight_total += array_b1[i].getWeight();
} //计算天平右边小球的总重量
for(int i=0;i<array_b2_length;i++)
{
array_b2_weight_total += array_b2[i].getWeight();
} //比较后给天平进行重置
if(array_b1_weight_total < array_b2_weight_total)
this.setState(-1);
else if(array_b1_weight_total > array_b2_weight_total)
this.setState(+1);
else
this.setState(0);
}
}//寻找小球类
class BallFinder
{
//假定次品一定在参数b1或b2中,而参数balance是一个天平类的对象
public int findBall(Ball b1,Ball b2,Balance balance)
{
//用于记录返回值,返回次品小球的编号
int result_index; //创建一个标准小球对象,默认的就是标准的
Ball b = new Ball(); //与一个标准球称量进行比较
balance.beginWeigh(b1,b);  //进行输出提示
System.out.println("\n第三次称量开始,方法是:");
System.out.print("    把0号小球和任意一个标准球进行称量,"); //判断
if(balance.getState() == 0)
{
result_index = b2.getIndex();
System.out.print("发现天平两边相等,判断如下:");
System.out.print("\n第三次称量结束,");
System.out.print(b2.getIndex() + "号球是次品!");
}
else
{
result_index = b1.getIndex();
System.out.print("发现天平两边不等,判断如下:");
System.out.print("\n第三次称量结束,");
System.out.print(b1.getIndex() + "号球是次品!");
}

//返回次品小球的编号
return result_index;
} //在该方法中,参数array_b的长度是4,而次品就在这个数组的后3个元素中
public int findBall(Ball[] array_b,Balance balance)
{
//用于记录返回值,返回次品小球的编号
int result_index; //创建一个标准小球对象,默认的就是标准的
Ball b = new Ball(); //先记录下称量前天平的状态,然后再进行下一步的操作
int oldState = balance.getState(); //创建临时数组array_b1_temp来模拟参数array_b,假定次品就在
//    array_b1_temp[1]、array_b1_temp[2]、array_b1_temp[3]中
Ball[] array_b1_temp = new Ball[4];
array_b1_temp[0] = new Ball();
array_b1_temp[1] = new Ball();
array_b1_temp[2] = new Ball();
array_b1_temp[3] = new Ball(); //创建另一个小球数组,其中放4个标准小球
Ball[] array_b2_temp = new Ball[4];
array_b2_temp[0] = new Ball();
array_b2_temp[1] = new Ball();
array_b2_temp[2] = new Ball();
array_b2_temp[3] = new Ball(); //将数组array_b1_temp中后3个元素的属性更改,以模拟参数array_b
array_b1_temp[1].setWeight(array_b[1].getWeight());
array_b1_temp[1].setIndex(array_b[1].getIndex());
array_b1_temp[2].setWeight(array_b[2].getWeight());
array_b1_temp[2].setIndex(array_b[2].getIndex());
array_b1_temp[3].setWeight(array_b[3].getWeight());
array_b1_temp[3].setIndex(array_b[3].getIndex()); //将天平左边的array_b1_temp[1]取下来,把一个标准小球b放上去
array_b1_temp[1].setWeight(b.getWeight()); //然后将天平左边的array_b1_temp[2]与天平右边的array_b2_temp[2]进行位置互换
int weight_temp = array_b2_temp[2].getWeight();
array_b2_temp[2].setWeight(array_b1_temp[2].getWeight());
array_b1_temp[2].setWeight(weight_temp); //输出提示
//如果传进来的参数是在0--3号第1组中,即在天平的左边
if(array_b[0].getIndex() == 0)
{
System.out.println("\n第三次称量开始,方法是:");
System.out.print("    先记录下称量前天平的状态,即左边是重还是轻的状态,");
System.out.print("再恢复到第二次\n    称量前的状态,");
System.out.print("将 1号小球从天平左边取下来,换上下面任意一个标准的\n    小球, ");
System.out.print("再把天平右边的任意一个小球和左边的2号小球进行位置互换,");
System.out.print("进\n    行第三次称量,");
}//接下页