前言
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;}}}}}
}
總結
算法題考察的是大家的邏輯思維能力,看來自己還是太菜了。學習不思則罔,思而不學則殆。學無止境,要不斷學習進步!