第七屆藍橋杯javaB組真題解析-分小組(第四題)


題目

 1 /*
 2 分小組
 3 
 4 9名運動員參加比賽,需要分3組進行預賽。
 5 有哪些分組的方案呢?
 6 
 7 我們標記運動員為 A,B,C,... I
 8 下面的程序列出了所有的分組方法。
 9 
10 該程序的正常輸出為:
11 ABC DEF GHI
12 ABC DEG FHI
13 ABC DEH FGI
14 ABC DEI FGH
15 ABC DFG EHI
16 ABC DFH EGI
17 ABC DFI EGH
18 ABC DGH EFI
19 ABC DGI EFH
20 ABC DHI EFG
21 ABC EFG DHI
22 ABC EFH DGI
23 ABC EFI DGH
24 ABC EGH DFI
25 ABC EGI DFH
26 ABC EHI DFG
27 ABC FGH DEI
28 ABC FGI DEH
29 ABC FHI DEG
30 ABC GHI DEF
31 ABD CEF GHI
32 ABD CEG FHI
33 ABD CEH FGI
34 ABD CEI FGH
35 ABD CFG EHI
36 ABD CFH EGI
37 ABD CFI EGH
38 ABD CGH EFI
39 ABD CGI EFH
40 ABD CHI EFG
41 ABD EFG CHI
42 ..... (以下省略,總共560行)。
43 
44 public class A
45 {
46     public static String remain(int[] a)
47     {
48         String s = "";
49         for(int i=0; i<a.length; i++){
50             if(a[i] == 0) s += (char)(i+'A');
51         }    
52         return s;
53     }
54     
55     public static void f(String s, int[] a)
56     {
57         for(int i=0; i<a.length; i++){
58             if(a[i]==1) continue;
59             a[i] = 1;
60             for(int j=i+1; j<a.length; j++){
61                 if(a[j]==1) continue;
62                 a[j]=1;
63                 for(int k=j+1; k<a.length; k++){
64                     if(a[k]==1) continue;
65                     a[k]=1;
66                     System.out.println(__________________________________);  //填空位置
67                     a[k]=0;
68                 }
69                 a[j]=0;
70             }
71             a[i] = 0;
72         }
73     }
74     
75     public static void main(String[] args)
76     {
77         int[] a = new int[9];        
78         a[0] = 1;
79         
80         for(int b=1; b<a.length; b++){
81             a[b] = 1;
82             for(int c=b+1; c<a.length; c++){
83                 a[c] = 1;
84                 String s = "A" + (char)(b+'A') + (char)(c+'A');
85                 f(s,a);
86                 a[c] = 0;
87             }
88             a[b] = 0;
89         }
90     }
91 }
92 
93 仔細閱讀代碼,填寫划線部分缺少的內容。
94 
95 注意:不要填寫任何已有內容或說明性文字。
96 */

 

答案

s + " "+ (char)(i+'A') + (char)(j+'A') + (char)(k+'A') + " " + remain(a)

 

 

代碼

 1 public class Main
 2 {
 3     public static String remain(int[] a)
 4     {
 5         String s = "";
 6         for(int i=0; i<a.length; i++){
 7             if(a[i] == 0) s += (char)(i+'A');
 8         }
 9         return s;
10     }
11     
12     public static void f(String s, int[] a)
13     {
14         for(int i=0; i<a.length; i++){
15             if(a[i]==1) continue;
16             a[i] = 1;
17             for(int j=i+1; j<a.length; j++){
18                 if(a[j]==1) continue;
19                 a[j]=1;
20                 for(int k=j+1; k<a.length; k++){
21                     if(a[k]==1) continue;
22                     a[k]=1;
23                     System.out.println(s + " "+ (char)(i+'A') + (char)(j+'A') + (char)(k+'A') + " " + remain(a));  //填空位置
24                     a[k]=0;
25                 }
26                 a[j]=0;
27             }
28             a[i] = 0;
29         }
30     }
31     
32     public static void main(String[] args)
33     {
34         int[] a = new int[9];        
35         a[0] = 1;
36         
37         for(int b=1; b<a.length; b++){
38             a[b] = 1;
39             for(int c=b+1; c<a.length; c++){
40                 a[c] = 1;
41                 String s = "A" + (char)(b+'A') + (char)(c+'A');
42                 f(s,a);
43                 a[c] = 0;
44             }
45             a[b] = 0;
46         }
47     }
48 }

 

 

注釋

  就這個“九個人分三組” 分法來說,在我反復思考,百度之后,發現這個題給出的分組答案竟然是錯誤的,正確的分組方法應該有280種(用高中數學方法可以算出,或者你可以百度),而不是560種,在我研究了一下代碼的輸出情況發現,每一種情況都輸出了兩次,題目的要求是沒有順序分成三組,但是就題目給出的算法,每一種情況,都會有兩組是有先后順序的。

  吐槽完畢然后來說這個題目

  題目給出的代碼思路是抓住 ‘A’ 不放,先找出所有的可以由‘A’組成的,單個小組項,然后從剩下的六個人中,隨機抽三個人,組成一組,然后結合剩下的三個人,一起構成一種情況輸出來,到這里你大概就能明白過來這個代碼就這個題目而言到底是錯在哪兒了,是因為在確定完‘A’所在的小組項之后,剩下的六個人中是隨機抽取三個人的,所以隨機抽取三個人,和剩下的三個人,就有個先后順序了! 到這里大家明白了吧。

  繼續講解這個代碼,這個思路是全排列的遞歸方法的一個針對題目的一個轉化,先聲明一個數組用作標記,用來標記本次的循環小節中先后抽取了誰,每一個循環小節都會標記一個人(a[b]=1或者a[c]=1),然后在本次循環結束時,在把標記清除,開始下一循環小節

 1     public static void main(String[] args)
 2     {
 3         int[] a = new int[9];        
 4         a[0] = 1;
 5         
 6         for(int b=1; b<a.length; b++){
 7             a[b] = 1;
 8             for(int c=b+1; c<a.length; c++){
 9                 a[c] = 1;
10                 String s = "A" + (char)(b+'A') + (char)(c+'A');
11                 f(s,a);
12                 a[c] = 0;
13             }
14             a[b] = 0;
15         }
16     }

 

  這個就是第一步 確定帶‘A’項,並把第一項存儲到一個字符串中,外層for循環是用來標記帶‘A’項中的第二個人,內層是標記第三個人。 然后開始到第二步:從六個人中抽取三個人(f(s,a)

 1     public static void f(String s, int[] a)
 2     {
 3         for(int i=0; i<a.length; i++){
 4             if(a[i]==1) continue;
 5             a[i] = 1;
 6             for(int j=i+1; j<a.length; j++){
 7                 if(a[j]==1) continue;
 8                 a[j]=1;
 9                 for(int k=j+1; k<a.length; k++){
10                     if(a[k]==1) continue;
11                     a[k]=1;
12                     System.out.println(s + " "+ (char)(i+'A') + (char)(j+'A') + (char)(k+'A') + " " + remain(a));  //填空位置
13                     a[k]=0;
14                 }
15                 a[j]=0;
16             }
17             a[i] = 0;
18         }
19     }

 

  這個方法中三層for循環用來確定六個人中被隨機抽取的三個人,由外到內依次是,第一個,第二個,第三個,並做上標記 所以中間的三個字母可以表示為

(char)(i+'A') + (char)(j+'A') + (char)(k+'A') 

 

  還有最后一個方法 remain() 方法

1     public static String remain(int[] a)
2     {
3         String s = "";
4         for(int i=0; i<a.length; i++){
5             if(a[i] == 0) s += (char)(i+'A');
6         }
7         return s;
8     }

 

 

  用於判斷沒有被標記的剩下三個人是誰,然后用字符串存儲並返回。

  到次大家應該可以弄明白整個代碼了吧 :)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM