前言
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-7
int 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,9
int num21=weights[0]+weights[1];
int num22=weights[8]+weights[9];
if(num21==num22){
//第二次平衡,次品在10-11里面,第三次称重正品组拿一个,比如0次品组拿一个比如10
int num31=weights[0];
int num32=weights[10];
if(num31==num32){
//第三次平衡,次品为11
return 11;
}else{
//第三次不平衡,次品为10
return 10;
}
}else{
//第二次不平衡,次品在8-9里面,第三次称重正品组拿一个,比如0次品组拿一个比如8
int num31=weights[0];
int num32=weights[8];
if(num31==num32){
//第三次平衡,次品为9
return 9;
}else{
//第三次不平衡,次品为8
return 8;
}
}
}else{
//第一次不平衡,次品在0-7里面,第二次称重则拿0,1,4和3,7,8
int num21=weights[0]+weights[1]+weights[4];
int num22=weights[3]+weights[7]+weights[8];
if(num21==num22){
//第二次平衡,次品在2和5,6里面,第三次称重5,6
int 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,1
int 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,3
int 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,3
int num31=weights[0];
int num32=weights[3];
if(num31==num32){
//第三次平衡,则4是次品
return 4;
}else {
//第三次不平衡,则3是次品
return 3;
}
}else{
//第一次0-3重,次品在0,1和7里面,第三次称重0,1
int 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-7
int 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,9
int num21=weights[0]+weights[1];
int num22=weights[8]+weights[9];
if(num21==num22){
//第二次平衡,次品在10-11里面,第三次称重正品组拿一个,比如0次品组拿一个比如10
int num31=weights[0];
int num32=weights[10];
if(num31==num32){
//第三次平衡,次品为11
return 11;
}else{
//第三次不平衡,次品为10
return 10;
}
}else{
//第二次不平衡,次品在8-9里面,第三次称重正品组拿一个,比如0次品组拿一个比如8
int num31=weights[0];
int num32=weights[8];
if(num31==num32){
//第三次平衡,次品为9
return 9;
}else{
//第三次不平衡,次品为8
return 8;
}
}
}else{
//第一次不平衡,次品在0-7里面,第二次称重则拿0,1,4和2,3,8
int num21=weights[0]+weights[1]+weights[4];
int num22=weights[2]+weights[3]+weights[8];
if(num21==num22){
//第二次平衡,次品在5,6,7里面,第三次称重5,6
int 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,8
int num31=weights[0];
int num32=weights[8];
if(num31==num32){
//第三次平衡,则1是次品
return 1;
}else {
//第三次不平衡,则0是次品
return 0;
}
}else{
//第一次0-3重,次品在2,3,4里面,第三次称重2,3
int 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,3
int 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,8
int num31=weights[0];
int num32=weights[8];
if(num31==num32){
//第三次平衡,则1是次品
return 1;
}else {
//第三次不平衡,则0是次品
return 0;
}
}
}
}
}
}
总结
算法题考察的是大家的逻辑思维能力,看来自己还是太菜了。学习不思则罔,思而不学则殆。学无止境,要不断学习进步!