題目及解析如下:
題目大致介紹:
第一題到第三題以及第六題、第七題是結果填空,方法不限只要得到最后結果就行
第四題和第五題是代碼填空題,主要考察算法基本功和編程基本功
第八題到第十題是編程題,要求編程解決問題
第一題 煤球數目(結果填空)
此題是一個找規律的題,規律比較好發現,第1層就是1,第二層就是1+2,第三層就是1+2+3,第n層就是1+2+3+、、、+n
但是注意看清楚題意,題目要求的是100層的總共的煤球數,不是求第100層的煤球數!
1 /* 2 有一堆煤球,堆成三角棱錐形。具體: 3 第一層放1個, 4 第二層3個(排列成三角形), 5 第三層6個(排列成三角形), 6 第四層10個(排列成三角形), 7 .... 8 answer: 171700 9 */ 10 public class t1 { 11 private static int f(int n){ // 算第n層有多少個 12 int res = 0; 13 for(int i=1; i<=n; i++){ 14 res += i; 15 } 16 17 return res; 18 } 19 20 private static int cal(int n){ 21 int res = 0; 22 for(int i=1; i<=n; i++){ 23 res += f(i); 24 } 25 return res; 26 } 27 28 public static void main(String[] args) { 29 // test 30 System.out.println(f(1)); 31 System.out.println(f(2)); 32 System.out.println(f(3)); 33 System.out.println(f(4)); 34 35 // result 36 System.out.println(cal(100)); // 171700 37 } 38 }
第二題 生日蠟燭(結果填空)
此題也比較簡單,直接暴力即可
1 /* 2 生日蠟燭: 3 某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。 4 現在算起來,他一共吹熄了236根蠟燭。 5 請問,他從多少歲開始過生日party的? 6 請填寫他開始過生日party的年齡數。 7 注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。 答案: 26 8 */ 9 public class t2 { 10 public static void main(String[] args) { 11 for(int i=1; i<=100; i++){ 12 int t = 0; 13 for(int j=i; j<=100; j++){ 14 t += j; 15 if(t==236){ 16 System.out.println(i + " " + j); // 26 33 17 // test: 18 System.out.println(26+27+28+29+30+31+32+33); 19 } 20 if(t>236){ 21 break; 22 } 23 } 24 } 25 } 26 }
第三題 湊算式(結果填空)
有兩種解法
第一種:暴力法
1 public class t3 { 2 private static boolean check(int i, int j, int k, int l, int a, int b, 3 int c, int d, int e) { 4 // 抽屜原理 5 int[] array = new int[10]; 6 array[i] += 1; 7 array[j] += 1; 8 array[k] += 1; 9 array[l] += 1; 10 array[a] += 1; 11 array[b] += 1; 12 array[c] += 1; 13 array[d] += 1; 14 array[e] += 1; 15 for (int t = 1; t <= 9; t++) { 16 if (array[t] != 1) { 17 return false; 18 } 19 } 20 21 return true; 22 } 23 24 public static void main(String[] args) { 25 int res = 0; 26 for (int i = 1; i <= 9; i++) 27 for (int j = 1; j <= 9; j++) 28 for (int k = 1; k <= 9; k++) 29 for (int l = 1; l <= 9; l++) 30 for (int a = 1; a <= 9; a++) 31 for (int b = 1; b <= 9; b++) 32 for (int c = 1; c <= 9; c++) 33 for (int d = 1; d <= 9; d++) 34 for (int e = 1; e <= 9; e++) { 35 int A = j; 36 int B = k; 37 int C = l * 100 + a * 10 + b; 38 int D = c * 100 + d * 10 + e; 39 // System.out.println(s); 40 if (check(i, j, k, l, a, b, c, d, e)) { 41 if (i * B * D + A * D + B * C == 10 42 * B * D) { 43 res += 1; 44 } 45 } 46 } 47 System.out.println(res); 48 } 49 }
第二種 全排列
1 // 用全排列進行優化 2 3 public class t3 { 4 5 public static int res; 6 7 public static boolean check(int[] arr) { 8 int A = arr[0]; 9 int B = arr[1]; 10 int C = arr[2]; 11 int D = arr[3] * 100 + arr[4] * 10 + arr[5]; 12 int E = arr[6] * 100 + arr[7] * 10 + arr[8]; 13 // A + B/C + D/E == 10 14 if(B*E + C*D == (10 - A) * C * E) { 15 return true; 16 } 17 return false; 18 } 19 20 public static void f(int[] arr, int k) { 21 22 if (k >= arr.length) { 23 if (check(arr)) { 24 res += 1; 25 } 26 return; 27 } 28 29 for (int i = k; i < arr.length; i++) { 30 int t = arr[k]; 31 arr[k] = arr[i]; 32 arr[i] = t; 33 f(arr, k + 1); 34 t = arr[k]; 35 arr[k] = arr[i]; 36 arr[i] = t; 37 } 38 39 } 40 41 public static void main(String[] args) { 42 f(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 0); 43 System.out.println(res); // 29 44 } 45 }
第四題 分小組(代碼填空)
常規題,不斷嘗試查找規律即可
1 /* 分小組 2 9名運動員參加比賽,需要分3組進行預賽。有哪些分組的方案呢? 3 我們標記運動員為 A,B,C,... I 4 下面的程序列出了所有的分組方法。 5 該程序的正常輸出為: 6 ABC DEF GHI 7 ABC DEG FHI 8 ABC DEH FGI 9 ABC DEI FGH 10 ABC DFG EHI 11 ABC DFH EGI 12 ABC DFI EGH 13 ABC DGH EFI 14 ABC DGI EFH 15 ABC DHI EFG 16 ABC EFG DHI 17 ABC EFH DGI 18 ABC EFI DGH 19 ABC EGH DFI 20 ABC EGI DFH 21 ABC EHI DFG 22 ABC FGH DEI 23 ABC FGI DEH 24 ABC FHI DEG 25 ABC GHI DEF 26 ABD CEF GHI 27 ABD CEG FHI 28 ABD CEH FGI 29 ABD CEI FGH 30 ABD CFG EHI 31 ABD CFH EGI 32 ABD CFI EGH 33 ABD CGH EFI 34 ABD CGI EFH 35 ABD CHI EFG 36 ABD EFG CHI 37 ..... (以下省略,總共560行)。 38 39 */ 40 public class t4 { 41 public static void printArray(int[] arr){ 42 if(arr==null){ 43 return; 44 } 45 for (int i = 0; i < arr.length; i++) { 46 System.out.print(arr[i] + " "); 47 } 48 System.out.println(); 49 } 50 51 public static String remain(int[] a) 52 { 53 String s = ""; 54 for(int i=0; i<a.length; i++){ 55 if(a[i] == 0) s += (char)(i+'A'); 56 } 57 return s; 58 } 59 60 public static void f(String s, int[] a) 61 { 62 for(int i=0; i<a.length; i++){ 63 if(a[i]==1) continue; 64 a[i] = 1; 65 for(int j=i+1; j<a.length; j++){ 66 if(a[j]==1) continue; 67 a[j]=1; 68 for(int k=j+1; k<a.length; k++){ 69 if(a[k]==1) continue; 70 a[k]=1; 71 // printArray(a); // print array 72 System.out.println(s + " " + (char)(i+'A') + (char)(j+'A') + (char)(k+'A') + " " +remain(a)); //填空位置 73 a[k]=0; 74 } 75 a[j]=0; 76 } 77 a[i] = 0; 78 } 79 } 80 81 public static void main(String[] args) 82 { 83 int[] a = new int[9]; 84 a[0] = 1; 85 86 for(int b=1; b<a.length; b++){ 87 a[b] = 1; 88 for(int c=b+1; c<a.length; c++){ 89 a[c] = 1; 90 String s = "A" + (char)(b+'A') + (char)(c+'A'); 91 f(s,a); 92 a[c] = 0; 93 } 94 a[b] = 0; 95 } 96 97 } 98 99 }
第五題 抽簽(代碼填空)
遞歸:
1 /* 抽簽 2 X星球要派出一個5人組成的觀察團前往W星。 3 其中: 4 A國最多可以派出4人。 5 B國最多可以派出2人。 6 C國最多可以派出2人。 7 、、、 8 那么最終派往W星的觀察團會有多少種國別的不同組合呢? 9 10 下面的程序解決了這個問題。 11 數組a[] 中是每個國家可以派出的最多的名額。 12 程序執行結果為: 13 DEFFF 14 CEFFF 15 CDFFF 16 CDEFF 17 CCFFF 18 CCEFF 19 CCDFF 20 CCDEF 21 BEFFF 22 BDFFF 23 BDEFF 24 BCFFF 25 BCEFF 26 BCDFF 27 BCDEF 28 .... 29 (以下省略,總共101行) 30 31 */ 32 33 public class t5 34 { 35 public static int res; 36 public static void f(int[] a, int k, int n, String s) 37 { 38 // k -> 當前到了第幾個國家 39 // n -> 派出的人數總數 40 // s -> 結果字符串 41 if(k==a.length){ 42 // 遍歷完數組a一遍 43 if(n==0){ 44 // 一個解 45 System.out.println(s); 46 res += 1; 47 } 48 return; 49 } 50 51 String s2 = s; 52 for(int i=0; i<=a[k]; i++){ 53 f(a, k+1, n-i, s2); //填空位置 54 s2 += (char)(k+'A'); 55 } 56 } 57 58 public static void main(String[] args) 59 { 60 res = 0; 61 int[] a = {4,2,2,1,1,3}; 62 63 f(a,0,5,""); 64 System.out.println(res); 65 } 66 }
第六題 方格填數(結果填空)
經典解法:全排列
1 package 藍橋杯真題.javaB2016; 2 3 /* 4 方格填數 5 如下的10個格子 6 +--+--+--+ 7 | | | | 8 +--+--+--+--+ 9 | | | | | 10 +--+--+--+--+ 11 | | | | 12 +--+--+--+ 13 (如果顯示有問題,也可以參看【圖1.jpg】) 14 15 填入0~9的數字。要求:連續的兩個數字不能相鄰。 16 (左右、上下、對角都算相鄰) 17 18 一共有多少種可能的填數方案?請填寫表示方案數目的整數。 19 */ 20 public class t6 { 21 22 public static int res = 0; 23 24 public static boolean check(int[] arr) { 25 if (Math.abs(arr[0] - arr[1]) == 1 || Math.abs(arr[0] - arr[3]) == 1 || Math.abs(arr[0] - arr[4]) == 1 26 || Math.abs(arr[0] - arr[5]) == 1) { 27 return false; 28 } 29 30 if (Math.abs(arr[1] - arr[2]) == 1 || Math.abs(arr[1] - arr[4]) == 1 || Math.abs(arr[1] - arr[5]) == 1 31 || Math.abs(arr[1] - arr[6]) == 1) { 32 return false; 33 } 34 35 if(Math.abs(arr[2] - arr[5]) == 1 ||Math.abs(arr[2] - arr[6]) == 1) { 36 return false; 37 } 38 39 if(Math.abs(arr[3] - arr[4]) == 1 ||Math.abs(arr[3] - arr[7]) == 1 ||Math.abs(arr[3] - arr[8]) == 1) { 40 return false; 41 } 42 43 if(Math.abs(arr[4] - arr[5]) == 1 || Math.abs(arr[4] - arr[7]) == 1 || Math.abs(arr[4] - arr[8]) == 1 || 44 Math.abs(arr[4] - arr[9]) == 1) { 45 return false; 46 } 47 48 if(Math.abs(arr[5] - arr[6]) == 1 ||Math.abs(arr[5] - arr[8]) == 1 ||Math.abs(arr[5] - arr[9]) == 1) { 49 return false; 50 } 51 52 if(Math.abs(arr[6] - arr[9]) == 1) { 53 return false; 54 } 55 56 if(Math.abs(arr[7] - arr[8]) == 1) { 57 return false; 58 } 59 60 if(Math.abs(arr[8] - arr[9]) == 1) { 61 return false; 62 } 63 64 return true; 65 } 66 67 public static void f(int[] arr, int n) { 68 // 全排列經典代碼 69 if (n == arr.length) { 70 if (check(arr)) { 71 res++; 72 } 73 return; 74 } 75 76 for (int i = n; i < arr.length; i++) { 77 int temp = arr[i]; 78 arr[i] = arr[n]; 79 arr[n] = temp; 80 f(arr, n + 1); 81 temp = arr[i]; 82 arr[i] = arr[n]; 83 arr[n] = temp; 84 } 85 86 } 87 88 public static void main(String[] args) { 89 int[] arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 90 f(arr, 0); 91 System.out.println(res); 92 } 93 94 }
另外一種解法:剪枝
1 // 將方格補成五行六列 2 // 補充的默認填-10 3 // 然后遞歸一個一個填 不符合規則的就回溯 4 // 填到最后res++ 5 public class t6_2 { 6 7 public static int res = 0; 8 public static boolean[] vis = new boolean[10]; // 標記每個數是否已經使用 9 10 public static boolean check(int[][] arr, int i, int j) { 11 // 檢查當前元素的相鄰元素是否連續 12 for (int x = i - 1; x <= i + 1; x++) { 13 for (int y = j - 1; y <= j + 1; y++) { 14 if (Math.abs(arr[x][y] - arr[i][j]) == 1) { 15 // 相鄰元素是連續的 16 return false; 17 } 18 } 19 } 20 21 return true; 22 } 23 24 public static void f(int[][] arr, int x, int y) { 25 if (x == 3 && y == 4) { 26 // 之前所有都滿足就是一種情況 27 res++; 28 return; 29 } 30 31 for(int i=0; i<10; i++) { 32 // 從0到9中抽一個放到當前位置 33 if(!vis[i]) { // i沒有被用過 34 arr[x][y] = i; 35 if(!check(arr, x, y)) { 36 // 不滿足條件 恢復並continue 37 arr[x][y] = -10; 38 continue; 39 } 40 vis[i] = true; // 標記為已經訪問 41 if(y==4) { 42 f(arr, x+1, 1); // 當達每一行的邊界 換行 43 }else { 44 f(arr, x, y+1); // 繼續填右邊的格子 45 } 46 // 回溯 47 vis[i] = false; 48 arr[x][y] = -10; 49 } 50 } 51 } 52 53 public static void main(String[] args) { 54 55 int[][] arr = { { -10, -10, -10, -10, -10, -10 }, { -10, -10, 0, 0, 0, -10 }, { -10, 0, 0, 0, 0, -10 }, 56 { -10, 0, 0, 0, -10, -10 }, { -10, -10, -10, -10, -10, -10 }, }; 57 f(arr, 1, 2); 58 System.out.println(res); 59 60 } 61 62 }
第七題 剪郵票(結果填空)
第八題 四平方和(程序設計)
題目如下:
1 四平方和定理,又稱為拉格朗日定理: 2 每個正整數都可以表示為至多4個正整數的平方和。 3 如果把0包括進去,就正好可以表示為4個數的平方和。 4 比如: 5 5 = 0^2 + 0^2 + 1^2 + 2^2 6 7 = 1^2 + 1^2 + 1^2 + 2^2 7 (^符號表示乘方的意思) 8 對於一個給定的正整數,可能存在多種平方和的表示法。 9 要求你對4個數排序: 10 0 <= a <= b <= c <= d 11 並對所有的可能表示法按 a,b,c,d 為聯合主鍵升序排列,最后輸出第一個表示法 12 程序輸入為一個正整數N (N<5000000) 13 要求輸出4個非負整數,按從小到大排序,中間用空格分開 14 例如,輸入: 15 5 16 則程序應該輸出: 17 0 0 1 2 18 再例如,輸入: 19 12 20 則程序應該輸出: 21 0 2 2 2 22 再例如,輸入: 23 773535 24 則程序應該輸出: 25 1 1 267 838 26 資源約定: 27 峰值內存消耗(含虛擬機) < 256M 28 CPU消耗 < 3000ms 29 請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入…” 的多余內容。 30 所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。 31 注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。 32 注意:主類的名字必須是:Main,否則按無效代碼處理。
第一種思路:暴力法應該是四層循環,明顯復雜度很高,最后一層循環我們優化去掉就寫出來如下的做法:
1 import java.util.*; 2 3 public class t8 { 4 5 private static Scanner scanner; 6 7 public static void main(String[] args) { 8 scanner = new Scanner(System.in); 9 System.out.println(": "); // 提交代碼的時候注釋掉 10 int N = scanner.nextInt(); 11 // 前三個數 12 int a, b, c; 13 // 最后一個數 14 double d; 15 double tmp = Math.sqrt(N); // 減少時間復雜度 16 for (a = 0; a < tmp; a++) { 17 for (b = a; b < tmp; b++) { 18 for (c = b; c < tmp; c++) { 19 d = Math.sqrt(N - a * a - b * b - c * c); // 優化(去掉第四層循環) 20 if (d == (int) d) { 21 System.out.println(a + " " + b + " " + c + " " + (int) d); 22 return; 23 } 24 } 25 } 26 } 27 } 28 29 }
第二種思路: 用map緩存第三個參數和第四個參數,如下:
1 import java.util.*; 2 3 public class t8 { 4 5 private static Scanner scanner; 6 public static int N; 7 public static Map<Integer, Integer> cache = new HashMap<Integer, Integer>(); 8 9 public static void main(String[] args) { 10 scanner = new Scanner(System.in); 11 System.out.println(": "); // 提交代碼的時候注釋掉 12 N = scanner.nextInt(); 13 int a, b, c, d; 14 // 由小到大遍歷進行緩存c、d 15 for (c = 0; c * c <= N / 2; c++) { 16 for (d = 0; c * c + d * d <= N; d++) { 17 if (cache.get(c * c + d * d) == null) { 18 // 之前沒有保存過相應的緩存 19 cache.put(c * c + d * d, c); 20 } 21 } 22 } 23 24 for (a = 0; a * a <= N / 4; a++) { 25 for (b = 0; a * a + b * b <= N / 2; b++) { 26 if (cache.get(N - a * a - b * b) != null) { 27 // 之前保存過相應的緩存 28 c = cache.get(N - a * a - b * b); 29 d = (int) Math.sqrt(N - a * a - b * b - c * c); 30 System.out.println(a + " " + b + " " + c + " " + d); 31 return; 32 } 33 } 34 } 35 36 } 37 38 }
第九題 取球博弈(程序設計)
第十題 壓縮變換(程序設計)
第九題第十題有一定難度,不看了、、、