题目:十二个乒乓球,其中一个质量有问题,或轻或重,用天枰称量3次找出这个球,并得知其情种情况。
思路整理:
12个球分成三组,分别标记为a1,a2,a3,a4 b1,b2,b3,b4 c1,c2,c3,c4
首先明确几点隐藏条件:
1.如果天枰不平衡,就表示坏球一定在天平上,那么剩下的球一定都是标准球,反之亦然。
2.每次平衡与不平衡的比较结果,都可作为下次比较的判断依据。
3.倘若一次比较天枰发生倾斜,那么再比较时,刚刚从天平上拿下去的球,从一边移动到另一边的球、保持原位不动的球这3种情况的球,再结合上次和本次的比较结果,可以进行坏球判断。
第一次称量 a1+a2+a3+a4 与 b1+b2+b3+b4
假设平衡,那么坏球一定在C组中,第二次称量,则比较c1+c2与c3+a1,假设c1+c2>c3+a1:第三次称量,则比较c1与c2,若c1>c2 则c1是较重于普通球;若c1==c2 则c3较轻于普通球;若c1<c2,则c2重于普通球。回到第二次称量,假设c1+c2==c3+a1:第三次称量,比较c4与a1,结果明显。回到第二次称量,假设c1+c2<c3+a1:第三次称量,比较c1与c2,若c1>c2,则c2轻于普通球;若c1==c2,则c3重于普通球;若c1<c2,则c1轻于普通球。至此,C组异常球的情况判断完毕
回到第一次称量,假设a1+a2+a3+a4>b1+b2+b3+b4 ,第二次称量,比较a1+a2+b1+b2与b3+c1+c2+c3 若大于,则第三次称量,比较a1与a2,若a1>a2,则a1重于一般球;若a1<a2,则a2重于一般球;若a1==a2,则b3轻于一般球。回到第二次称量,若等于,则第三次称量,比较a3与a4,若a3>a4,则a3重于一般球;若a3==a4,则b4轻于一般球;若a3<a4,则a4重于一般球。回到第二次称量,若小于,则说明坏球在b1与b2之间,第三次称量,比较b1与b2,若b1>b2,则b2轻于一般球,否则,b1轻于一般球。
回到第一次称量,若a1+a2+a3+a4<b1+b2+b3+b4,将b1与a1,b2与a2,b3与a3,b4与a4的序号对调按照上一种情况处理,获得的结果,再将对调对调回来即可。
至此,所有球的异常情况全部轮循完毕。
程序验证
int[] bolls = new int[12];// 记录12个球的重量, int criterionWeight = 3;// 普通球重量是3,假定有问题的球质量在1~2,4~5之间 for (int i = 0; i < bolls.length; i++) {// 设置所有球重量为标准重量 bolls[i] = criterionWeight; } Random random = new Random(); int badWeight = criterionWeight;// 坏球重量,用于对比判断结果 int badIndex = random.nextInt(12);// 坏球下标,用于对比判断结果 while ((badWeight = random.nextInt(5) + 1) == criterionWeight) ; System.out.println("坏球:" + (1 + badIndex) + ",比一般球" + (badWeight > criterionWeight ? "重" : "轻")); bolls[badIndex] = badWeight;// 设置随机坏球及其重量 int libraLeft, libraRight;// 每次称量天枰左右的总值 // 开始找坏球 libraLeft = bolls[0] + bolls[1] + bolls[2] + bolls[3];// 天枰左边总和 libraRight = bolls[4] + bolls[5] + bolls[6] + bolls[7];// 天枰右边总和 // 第一次称量 if (libraLeft == libraRight) { // 说明坏球在8,9,10,11里 libraLeft = bolls[8] + bolls[9]; libraRight = bolls[10] + bolls[0]; // 第二次称量 if (libraLeft == libraRight) { // 说明坏球是11 libraLeft = bolls[11]; libraRight = bolls[0]; // 第三次称量 if (libraLeft > libraRight) { System.out.println("坏球是12号球,比普通球重"); } else { System.out.println("坏球是12号球,比普通球轻"); } } else { boolean leftWeight = libraLeft > libraRight; libraLeft = bolls[8]; libraRight = bolls[9]; // 第三次称量 if (libraLeft == libraRight) {// 结合第二次称量结果得出以下结论 if (leftWeight) { System.out.println("坏球是11号,且比普通球轻"); } else { System.out.println("坏球是11号,且比普通球重"); } } else if (libraLeft < libraRight) { if (leftWeight) { System.out.println("说明坏球是10号球,且比普通球重"); } else { System.out.println("说明坏球是9号,且比普通球轻"); } } else { if (leftWeight) { System.out.println("说明坏球是9号,且比普通球重"); } else { System.out.println("说明坏球是10号,且比普通球轻"); } } } } else { boolean update = false;// 标记是否左右互换。 if (libraLeft < libraRight) {// 左边重与右边重在运算过程中是相反的,运算逻辑相同,所以只对结果做处理即可 int temp; for (int i = 0; i < 4; i++) {// 左右互换。 temp = bolls[i]; bolls[i] = bolls[i + 4]; bolls[i + 4] = temp; } update = true; } // 所以到这里一定是左边比右边重 // 说明剩下的4个球是标准球 libraLeft = bolls[0] + bolls[1] + bolls[4] + bolls[5]; libraRight = bolls[6] + bolls[8] + bolls[9] + bolls[10]; // 第二次称量 if (libraLeft > libraRight) { // 说明有问题的球在1、2、7号球里 libraLeft = bolls[0]; libraRight = bolls[1]; // 第三次称量 if (libraLeft == libraRight) { if (update) { System.out.println("坏球是3号球,比一般球轻"); } else { System.out.println("坏球是7号球,比一般球轻"); } } else if (libraLeft > libraRight) { if (update) { System.out.println("坏球是5号球,比一般球重"); } else { System.out.println("坏球是1号球,比一般球重"); } } else { if (update) { System.out.println("坏球是6号球,比一般球重"); } else { System.out.println("坏球是2号球,比一般球重"); } } } else if (libraLeft == libraRight) { // 说明有问题的球在3,4,8号球里 libraLeft = bolls[2]; libraRight = bolls[3]; if (libraLeft == libraRight) { if (update) { System.out.println("坏球是4号球,且比一般球轻"); } else { System.out.println("坏球是8号球,且比一般球轻"); } } else if (libraLeft > libraRight) { if (update) { System.out.println("坏球是7号球,且比一般球重"); } else { System.out.println("坏球是3号球,且比一般球重"); } } else { if (update) { System.out.println("坏球是8号球,且比一般球重"); } else { System.out.println("坏球是4号球,且比一般球重"); } } } else { // 说明坏球在5、6中 libraLeft = bolls[4]; libraRight = bolls[0]; if (libraLeft > libraRight) { if (update) { System.out.println("坏球是1号球,比一般球重"); } else { System.out.println("坏球是5号球,比一般球重"); } } else if (libraLeft == libraRight) { if (update) { System.out.println("坏球是2号球,比一般球轻"); } else { System.out.println("坏球是6号球,比一般球轻"); } } else { if (update) { System.out.println("坏球是1号球,比一般球轻"); } else { System.out.println("坏球是5号球,比一般球轻"); } } } }
代码暂且记录如此,稍带整理后再做更新。