前言
B站上看到个视频:为什么有人不认可清北的学生大多是智商高的?
然后试了下,发现我真菜
自己的思路(失败)
三次称重要获取到12个乒乓球中那个是次品,我想着将12个小球编号,分为四组,每组三个。
编号可以是:123456789abc,分组为123,456,789,abc
第一次称重123VS456,结果可能是平衡或者不平衡
平衡时就表示这六个是准的,次品在剩下六个789abc里面
不平衡就表示次品在123456里面。
以不平衡为例
第二次称重123VS789,789是正品,如果平衡则123也是正品次品在456里面,不平衡则次品在123里面。
这里以不平衡为例,则次品在123里面。
第三次称重,123里面拿两个,比如1VS2,平衡则3是次品,不平衡则次品在12里面。结合第一次称重结果,如果第一次是123轻则轻的是次品
上面以不平衡为例是可以查找到次品的,但是以平衡为例,则查找不到次品
以平衡为例
第二次称重123VS789,123是正品,如果平衡则789也是正品次品在9,10,11里面,不平衡则次品在789里面。
以平衡为例,则次品在9,10,11里面。
第三次称重,9,10,11里面拿两个,比如9VS10,平衡则11是次品,不平衡时因为第一二次都是平衡的不知道次品和正品的重量关系(轻还是重)此时判断不出来9,10那个是次品。
别人的方法
首先为球编号123456789abc
第一次1234对比5678
(1)若1234与5678不等重,则9abc排除嫌疑。
不妨设1234轻
第二次125与489称
(1.1)若125轻,则说明12轻或8重,此时称1与2即可
(1.2)若489轻,则说明5重或4轻,此时称4与9或5与9即可
(1.3)若等重,则说明3轻或67重,6与7称即可
(2)若1234与5678等重,则次品在9abc中。易得,略。
public class Test12 {public static void main(String[] args) {int[]weights0=new int[]{0,1,1,1,1,1,1,1,1,1,1,1};int[]weights1=new int[]{1,-1,1,1,1,1,1,1,1,1,1,1};int[]weights2=new int[]{1,1,2,1,1,1,1,1,1,1,1,1};int[]weights3=new int[]{1,1,1,3,1,1,1,1,1,1,1,1};int[]weights4=new int[]{1,1,1,1,4,1,1,1,1,1,1,1};int[]weights5=new int[]{1,1,1,1,1,5,1,1,1,1,1,1};int[]weights6=new int[]{1,1,1,1,1,1,6,1,1,1,1,1};int[]weights7=new int[]{1,1,1,1,1,1,1,7,1,1,1,1};int[]weights8=new int[]{1,1,1,1,1,1,1,1,8,1,1,1};int[]weights9=new int[]{1,1,1,1,1,1,1,1,1,9,1,1};int[]weights10=new int[]{1,1,1,1,1,1,1,1,1,1,10,1};int[]weights11=new int[]{1,1,1,1,1,1,1,1,1,1,1,11};System.out.println("weights0:"+checkWeights(weights0));System.out.println("weights1:"+checkWeights(weights1));System.out.println("weights2:"+checkWeights(weights2));System.out.println("weights3:"+checkWeights(weights3));System.out.println("weights4:"+checkWeights(weights4));System.out.println("weights5:"+checkWeights(weights5));System.out.println("weights6:"+checkWeights(weights6));System.out.println("weights7:"+checkWeights(weights7));System.out.println("weights8:"+checkWeights(weights8));System.out.println("weights9:"+checkWeights(weights9));System.out.println("weights10:"+checkWeights(weights10));System.out.println("weights11:"+checkWeights(weights11));}public static int checkWeights(int[]weights) {//12个乒乓球重量数组,按数组位置分为0-11//第一次 0-3VS4-7int num11=weights[0]+weights[1]+weights[2]+weights[3];int num12=weights[4]+weights[5]+weights[6]+weights[7];if(num11==num12){//第一次平衡,次品在8-11里面,第二次称重正品组拿两个,比如0,1次品组拿两个比如8,9int num21=weights[0]+weights[1];int num22=weights[8]+weights[9];if(num21==num22){//第二次平衡,次品在10-11里面,第三次称重正品组拿一个,比如0次品组拿一个比如10int num31=weights[0];int num32=weights[10];if(num31==num32){//第三次平衡,次品为11return 11;}else{//第三次不平衡,次品为10return 10;}}else{//第二次不平衡,次品在8-9里面,第三次称重正品组拿一个,比如0次品组拿一个比如8int num31=weights[0];int num32=weights[8];if(num31==num32){//第三次平衡,次品为9return 9;}else{//第三次不平衡,次品为8return 8;}}}else{//第一次不平衡,次品在0-7里面,第二次称重则拿0,1,4和3,7,8int num21=weights[0]+weights[1]+weights[4];int num22=weights[3]+weights[7]+weights[8];if(num21==num22){//第二次平衡,次品在2和5,6里面,第三次称重5,6int num31=weights[5];int num32=weights[6];//需要和第一次称重结合分析if(num31==num32){//第三次平衡,则2是次品return 2;}else if(num31<num32){//第三次不平衡,5轻,如果第一次0-3轻,则6是次品否则5是次品if(num11<num12){return 6;}else {return 5;}}else{//第三次不平衡,6轻,如果第一次0-3轻,则5是次品否则6是次品if(num11<num12){return 5;}else {return 6;}}}else if(num21<num22){//第二次不平衡,0,1,4小于3,7,8 需要和第一次称重结合分析if(num11<num12){//第一次0-3轻,次品在0,1和7里面,第三次称重0,1int num31=weights[0];int num32=weights[1];if(num31==num32){//第三次平衡,则7是次品return 7;}else {if(num31<num32){//第三次不平衡,0轻,第一次0-3轻,则0是次品return 0;}else{//第三次不平衡,1轻,第一次0-3轻,则1是次品return 1;}}}else{//第一次0-3重,次品在3和4里面,第三次称重0,3int num31=weights[0];int num32=weights[3];if(num31==num32){//第三次平衡,则4是次品return 4;}else {//第三次不平衡,则3是次品return 3;}}}else{//第二次不平衡,0,1,4大于3,7,8 需要和第一次称重结合分析if(num11<num12){//第一次0-3轻,次品在3和4里面,第三次称重0,3int num31=weights[0];int num32=weights[3];if(num31==num32){//第三次平衡,则4是次品return 4;}else {//第三次不平衡,则3是次品return 3;}}else{//第一次0-3重,次品在0,1和7里面,第三次称重0,1int num31=weights[0];int num32=weights[1];if(num31==num32){//第三次平衡,则7是次品return 7;}else {if(num31<num32){//第三次不平衡,0轻,第一次0-3重,则1是次品return 1;}else{//第三次不平衡,1轻,第一次0-3重,则0是次品return 0;}}}}}}
}
测试结果
weights0:0
weights1:1
weights2:2
weights3:3
weights4:4
weights5:5
weights6:6
weights7:7
weights8:8
weights9:9
weights10:10
weights11:11
AI的答案
步骤1:将12个乒乓球分为三组,每组4个,分别标记为A、B、C。
第一次称重:取A组和B组进行称重。
- 情况A:如果两边平衡,那么次品在C组中。
- 情况B:如果两边不平衡,假设A组重,那么次品有两种可能:
- 可能1:次品在A组中(且更重)。
- 可能2:次品在B组中(且更轻)。
步骤2:
- 如果第一次称重是情况A(A组和B组平衡):
- 将C组的乒乓球分为两组,每组2个,分别标记为C1和C2。将C1放在天平的左边,从A组(或B组,因为它们是正常的)取2个乒乓球放在天平的右边进行称重。
- 情况A1:如果平衡,次品在C2中。
- 情况A2:如果不平衡,次品在C1中,并且可以直接通过比较确定它是更重还是更轻。
- 将C组的乒乓球分为两组,每组2个,分别标记为C1和C2。将C1放在天平的左边,从A组(或B组,因为它们是正常的)取2个乒乓球放在天平的右边进行称重。
- 如果第一次称重是情况B(A组和B组不平衡):
- 将A组的乒乓球分为两组,每组2个,分别标记为A1和A2。将B组的乒乓球也分为两组,第一组1个和剩下的3个,分别标记为B1(1个)和B2(3个)。进行以下称重:将A1和B1放在天平左边,A2和1个正常乒乓球(来自C组已知正常的)放在天平右边。
- 情况B1:如果平衡,次品在B2中,且更轻。
- 情况B2:如果不平衡,则有两种可能性:
- 可能性B2.1:如果左边重(即A1和B1重),那么次品有两种可能:A1中更重的一个,或者B1中更轻的一个(因为假设A组整体更重,所以B1更轻)。
- 可能性B2.2:如果右边重(即A2和正常乒乓球重),那么次品在A2中,且更重。
- 将A组的乒乓球分为两组,每组2个,分别标记为A1和A2。将B组的乒乓球也分为两组,第一组1个和剩下的3个,分别标记为B1(1个)和B2(3个)。进行以下称重:将A1和B1放在天平左边,A2和1个正常乒乓球(来自C组已知正常的)放在天平右边。
步骤3:
- 如果第二次称重是情况A1(次品在C2中):取C2中的两个乒乓球进行称重,即可确定哪个是次品,并判断其轻重。
- 如果第二次称重是情况B1(次品在B2中):取B2中的两个乒乓球进行称重,轻的一个即为次品。
- 如果第二次称重是情况B2(次品在A1或B1或A2中):
- 如果可能性B2.1(A1中更重的一个,或者B1中更轻的一个):取A1中的两个乒乓球进行称重,重的一个即为次品;如果A1中两个乒乓球平衡,则B1为次品且更轻。
- 如果可能性B2.2(次品在A2中):A2中的两个乒乓球进行称重,重的一个即为次品。
通过这种方法,我们可以在三次称重内准确地找出次品,并确定其轻重。
AI的逻辑基本可以理解,但是略显混乱。整体上和上面的方法一样
代码
public class Test12 {public static void main(String[] args) {int[]weights0=new int[]{0,1,1,1,1,1,1,1,1,1,1,1};int[]weights1=new int[]{1,-1,1,1,1,1,1,1,1,1,1,1};int[]weights2=new int[]{1,1,2,1,1,1,1,1,1,1,1,1};int[]weights3=new int[]{1,1,1,3,1,1,1,1,1,1,1,1};int[]weights4=new int[]{1,1,1,1,4,1,1,1,1,1,1,1};int[]weights5=new int[]{1,1,1,1,1,5,1,1,1,1,1,1};int[]weights6=new int[]{1,1,1,1,1,1,6,1,1,1,1,1};int[]weights7=new int[]{1,1,1,1,1,1,1,7,1,1,1,1};int[]weights8=new int[]{1,1,1,1,1,1,1,1,8,1,1,1};int[]weights9=new int[]{1,1,1,1,1,1,1,1,1,9,1,1};int[]weights10=new int[]{1,1,1,1,1,1,1,1,1,1,10,1};int[]weights11=new int[]{1,1,1,1,1,1,1,1,1,1,1,11};System.out.println("weights0:"+checkWeights(weights0));System.out.println("weights1:"+checkWeights(weights1));System.out.println("weights2:"+checkWeights(weights2));System.out.println("weights3:"+checkWeights(weights3));System.out.println("weights4:"+checkWeights(weights4));System.out.println("weights5:"+checkWeights(weights5));System.out.println("weights6:"+checkWeights(weights6));System.out.println("weights7:"+checkWeights(weights7));System.out.println("weights8:"+checkWeights(weights8));System.out.println("weights9:"+checkWeights(weights9));System.out.println("weights10:"+checkWeights(weights10));System.out.println("weights11:"+checkWeights(weights11));}public static int checkWeights(int[]weights) {//12个乒乓球重量数组,按数组位置分为0-11//第一次 0-3VS4-7int num11=weights[0]+weights[1]+weights[2]+weights[3];int num12=weights[4]+weights[5]+weights[6]+weights[7];if(num11==num12){//第一次平衡,次品在8-11里面,第二次称重正品组拿两个,比如0,1次品组拿两个比如8,9int num21=weights[0]+weights[1];int num22=weights[8]+weights[9];if(num21==num22){//第二次平衡,次品在10-11里面,第三次称重正品组拿一个,比如0次品组拿一个比如10int num31=weights[0];int num32=weights[10];if(num31==num32){//第三次平衡,次品为11return 11;}else{//第三次不平衡,次品为10return 10;}}else{//第二次不平衡,次品在8-9里面,第三次称重正品组拿一个,比如0次品组拿一个比如8int num31=weights[0];int num32=weights[8];if(num31==num32){//第三次平衡,次品为9return 9;}else{//第三次不平衡,次品为8return 8;}}}else{//第一次不平衡,次品在0-7里面,第二次称重则拿0,1,4和2,3,8int num21=weights[0]+weights[1]+weights[4];int num22=weights[2]+weights[3]+weights[8];if(num21==num22){//第二次平衡,次品在5,6,7里面,第三次称重5,6int num31=weights[5];int num32=weights[6];//需要和第一次称重结合分析if(num31==num32){//第三次平衡,则7是次品return 7;}else if(num31<num32){//第三次不平衡,5轻,如果第一次0-3轻,则6是次品否则5是次品if(num11<num12){return 6;}else {return 5;}}else{//第三次不平衡,6轻,如果第一次0-3轻,则5是次品否则6是次品if(num11<num12){return 5;}else {return 6;}}}else if(num21<num22){//第二次不平衡,0,1,4小于2,3,8 需要和第一次称重结合分析if(num11<num12){//第一次0-3轻,次品在0,1里面,第三次称重0,8int num31=weights[0];int num32=weights[8];if(num31==num32){//第三次平衡,则1是次品return 1;}else {//第三次不平衡,则0是次品return 0;}}else{//第一次0-3重,次品在2,3,4里面,第三次称重2,3int num31=weights[2];int num32=weights[3];if(num31==num32){//第三次平衡,则3是次品return 4;}else if(num31>num32){//第三次不平衡,2重,则2是次品return 2;}else{//第三次不平衡,2轻,则3是次品return 3;}}}else{//第二次不平衡,0,1,4大于2,3,8 需要和第一次称重结合分析if(num11<num12){//第一次0-3轻,次品在2,3,4里面,第三次称重2,3int num31=weights[2];int num32=weights[3];if(num31==num32){//第三次平衡,则3是次品return 4;}else if(num31>num32){//第三次不平衡,2重,则3是次品return 3;}else{//第三次不平衡,2轻,则2是次品return 2;}}else{//第一次0-3重,次品在0,1里面,第三次称重0,8int num31=weights[0];int num32=weights[8];if(num31==num32){//第三次平衡,则1是次品return 1;}else {//第三次不平衡,则0是次品return 0;}}}}}
}
总结
算法题考察的是大家的逻辑思维能力,看来自己还是太菜了。学习不思则罔,思而不学则殆。学无止境,要不断学习进步!