2014年 第5届 蓝桥杯 Java B组 省赛解析及总结
- 藍橋杯 Java B組 省賽決賽 真題詳解及小結匯總【2013年(第4屆)~2021年(第12屆)】
- 第11屆 藍橋杯-第1、2次模擬(軟件類)真題-(2020年3月、4月)-官方講解視頻
- 說明:部分題解思路及程序代碼 源自?藍橋杯 官網視頻(Java B組歷年真題解析)
目? ?錄
一、武功秘籍
二、切面條
三、猜字母
四、大衍數列
五、圓周率
六、奇怪的分式
七、撲克排序
八、分糖果
九、地宮取寶
解法一
解法二:滿分代碼
解法三:42分
解法四:57分
十、矩陣翻硬幣
字符、字符串 與 BigInteger 相互轉化
小結
一、武功秘籍
標題:武功秘籍
? ? 小明到X山洞探險,撿到一本有破損的武功秘籍(2000多頁!當然是偽造的)。他注意到:書的第10頁和第11頁在同一張紙上,但第11頁和第12頁不在同一張紙上。
? ? 小明只想練習該書的第81頁到第92頁的武功,又不想帶著整本書。請問他至少要撕下多少張紙帶走?
這是個整數,請通過瀏覽器提交該數字,不要填寫任何多余的內容。
【答案】:7?? ? ? ? ? ? ? ? ? ? ? ? ?注意書的構成方式。
二、切面條
標題:切面條
? ? 一根高筋拉面,中間切一刀,可以得到2根面條。
? ? 如果先對折1次,中間切一刀,可以得到3根面條。
? ? 如果連續對折2次,中間切一刀,可以得到5根面條。
? ? 那么,連續對折10次,中間切一刀,會得到多少面條呢?
答案是個整數,請通過瀏覽器提交答案。不要填寫任何多余的內容。
【答案】:1025
三、猜字母
標題:猜字母
? ? 把abcd...s共19個字母組成的序列重復拼接106次,得到長度為2014的串。
? ? 接下來刪除第1個字母(即開頭的字母a),以及第3個,第5個等所有奇數位置的字母。
? ? 得到的新串再進行刪除奇數位置字母的動作。如此下去,最后只剩下一個字母,請寫出該字母。
答案是一個小寫字母,請通過瀏覽器提交答案。不要填寫任何多余的內容。
【答案】:q
package provincialGames_05_2014;public class A03_猜字母 {public static void main(String[] args) {char[] a = new char[2014];int index = 0;for (int i = 0; i < 106; i++) {for (int j = 0; j < 19; j++) {a[index++] = (char) ('a' + j);}} // for (int i = 0; i < 2014; i++) { // System.out.print(a[i] + " "); // }int len = 2014;while (len != 1) {int k = 0;for (int i = 1; i < len; i += 2) {a[k++] = a[i];}len = k;}System.out.println(a[0]);} }四、大衍數列
標題:大衍數列
? ? 中國古代文獻中,曾記載過“大衍數列”, 主要用于解釋中國傳統文化中的太極衍生原理。
? ? 它的前幾項是:0、2、4、8、12、18、24、32、40、50 ...
? ? 其規律是:對偶數項,是序號平方再除2,奇數項,是序號平方減1再除2。
? ? 以下的代碼打印出了大衍數列的前 100 項。
for(int i=1; i<100; i++)
{
?? ?if(________________) ?//填空
?? ??? ?System.out.println(i*i/2);
?? ?else
?? ??? ?System.out.println((i*i-1)/2);
}
? ? 請填寫劃線部分缺失的代碼。通過瀏覽器提交答案。
注意:不要填寫題面已有的內容,也不要填寫任何說明、解釋文字。?
【答案】:?i % 2 == 0
package provincialGames_05_2014_JavaB;public class A04_大衍數列 { // 奇偶數判斷:x % 2 == 0public static void main(String[] args) {for (int i = 1; i < 100; i++) {if (i % 2 == 0) // 填空System.out.println(i * i / 2);elseSystem.out.println((i * i - 1) / 2);}} }五、圓周率
標題:圓周率
? ? 數學發展歷史上,圓周率的計算曾有許多有趣甚至是傳奇的故事。其中許多方法都涉及無窮級數。
? ? 圖1.png中所示,就是一種用連分數的形式表示的圓周率求法。
圖1.png? ? 下面的程序實現了該求解方法。實際上數列的收斂對x的初始值 并不敏感。
? ? 結果打印出圓周率近似值(保留小數點后4位,并不一定與圓周率真值吻合)。
?? ?double x = 111;
?? ?for(int n = 10000; n>=0; n--){
?? ??? ?int i = 2 * n + 1;
?? ??? ?x = 2 + (i*i / x);
?? ?}
?? ?System.out.println(String.format("%.4f", ______________));
【答案】:4 / (x - 1))
?細心、極限思維
- n == 1: ? i == 3 ? --> ? x = 2 + ( 3 * 3 / x )
- n == 2: ? i == 5 ? --> ? x = 2 + ( 5 * 5 / x )
- n == 3: ? i == 7 ? --> ? x = 2 + ( 7 * 7 / x )
每次x都加2。所以,(4 / Pi) == (2 + x - 1) 。
最后的x多加了一個1。所以,輸出結果要減去一個1。
(4 / Pi) == (x - 1) , 所以,Pi == 4 / (x - 1) 。
package provincialGames_05_2014;public class A05_圓周率 {public static void main(String[] args) {double x = 111;for (int n = 10000; n >= 0; n--) {int i = 2 * n + 1; //把i變為奇數x = 2 + (i * i / x);}// x=2+1/x'System.out.println(String.format("%.4f", 4 / (x - 1)));} }六、奇怪的分式
標題:奇怪的分式
? ? 上小學的時候,小明經常自己發明新算法。一次,老師出的題目是:
? ? 1/4 乘以 8/5
? ? 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (參見圖1.png)
圖1.png??????? ? 老師剛想批評他,轉念一想,這個答案湊巧也對啊,真是見鬼!
? ? 對于分子、分母都是 1~9 中的一位數的情況,還有哪些算式可以這樣計算呢?
? ? 請寫出所有不同算式的個數(包括題中舉例的)。
? ? 顯然,交換分子分母后,例如:4/1 乘以 5/8 是滿足要求的,這算做不同的算式。
? ? 但對于分子分母相同的情況,2/2 乘以 3/3 這樣的類型太多了,不在計數之列!
注意:答案是個整數(考慮對稱性,肯定是偶數)。請通過瀏覽器提交。不要書寫多余的內容。
【答案】:14? ? ? ? ? ? ?考點:枚舉abcd、最大公約數
package provincialGames_05_2014_JavaB;public class A06_奇怪的分式 {private static int ans;public static void main(String[] args) {for (int a = 1; a < 10; a++) {for (int b = 1; b < 10; b++) {if (a == b) {continue;}for (int c = 1; c < 10; c++) {for (int d = 1; d < 10; d++) {if (c == d) {continue;}int gcd1 = gcd(a * c, b * d);int gcd2 = gcd(a * 10 + c, b * 10 + d);if (a * c / gcd1 == (a * 10 + c) / gcd2 && b * d / gcd1 == (b * 10 + d) / gcd2) { // 分子分母分別比較System.out.printf("%d %d %d %d\n", a, b, c, d); // 輸出a、b、c、d,進行驗算// System.out.println(a + "、" + b + "、" + c + "、" + d);ans++;}}}}}System.out.println(ans);}private static int gcd(int a, int b) {if (b == 0)return a;return gcd(b, a % b);} }七、撲克排序
標題:撲克序列
? ? A A 2 2 3 3 4 4, 一共4對撲克牌。請你把它們排成一行。
? ? 要求:兩個A中間有1張牌,兩個2之間有2張牌,兩個3之間有3張牌,兩個4之間有4張牌。
? ? 請填寫出所有符合要求的排列中,字典序最小的那個。
例如:22AA3344 比 A2A23344 字典序小。當然,它們都不是滿足要求的答案。
請通過瀏覽器提交答案。“A”一定不要用小寫字母a,也不要用“1”代替。字符間一定不要留空格。
【答案】:2342A3A4
全排列題目:2014 A 六角填數
- A_A
- 2__2
- 3___3
- 4____4
八、分糖果
標題:分糖果
? ? 有n個小朋友圍坐成一圈。老師給每個小朋友隨機發偶數個糖果,然后進行下面的游戲:
? ? 每個小朋友都把自己的糖果分一半給左手邊的孩子。
? ? 一輪分糖后,擁有奇數顆糖的孩子由老師補給1個糖果,從而變成偶數。
? ? 反復進行這個游戲,直到所有小朋友的糖果數都相同為止。
? ? 你的任務是預測在已知的初始糖果情形下,老師一共需要補發多少個糖果。
【格式要求】
? ? 程序首先讀入一個整數N(2<N<100),表示小朋友的人數。
? ? 接著是一行用空格分開的N個偶數(每個偶數不大于1000,不小于2)
? ? 要求程序輸出一個整數,表示老師需要補發的糖果數。
例如:輸入
3
2 2 4
程序應該輸出:
4
資源約定:
峰值內存消耗(含虛擬機) < 256M
CPU消耗 ?< 1000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多余內容。
所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效代碼處理。
九、地宮取寶
標題:地宮取寶
? ? X 國王有一個地宮寶庫。是 n x m 個格子的矩陣。每個格子放一件寶貝。每個寶貝貼著價值標簽。
? ? 地宮的入口在左上角,出口在右下角。
? ? 小明被帶到地宮的入口,國王要求他只能向右或向下行走。
? ? 走過某個格子時,如果那個格子中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它(當然,也可以不拿)。
? ? 當小明走到出口時,如果他手中的寶貝恰好是k件,則這些寶貝就可以送給小明。
? ? 請你幫小明算一算,在給定的局面下,他有多少種不同的行動方案能獲得這k件寶貝。
【數據格式】
? ? 輸入一行3個整數,用空格分開:n m k (1<=n,m<=50, 1<=k<=12)
? ? 接下來有 n 行數據,每行有 m 個整數 Ci (0<=Ci<=12)代表這個格子上的寶物的價值
? ? 要求輸出一個整數,表示正好取k個寶貝的行動方案數。該數字可能很大,輸出它對 1000000007 取模的結果。
例如,輸入:
2 2 2
1 2
2 1
程序應該輸出:
2
再例如,輸入:
2 3 2
1 2 3
2 1 5
程序應該輸出:
14
資源約定:
峰值內存消耗(含虛擬機) < 256M
CPU消耗 ?< 2000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多余內容。
所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效代碼處理。
解法一
public class _09地宮取寶 {private static final int MOD = 1000000007;static int[][] data;private static int n;private static int m;private static int k;public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();m = sc.nextInt();k = sc.nextInt();data = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {data[i][j] = sc.nextInt();}}for (int i = 0; i < 51; i++) {for (int j = 0; j < 51; j++) {for (int l = 0; l < 14; l++) {for (int o = 0; o < 14; o++) {cache[i][j][l][o] = -1;}}}}long ans = dfs(0, 0, -1, 0);System.out.println(ans);}static long[][][][] cache = new long[51][51][14][14];private static long dfs(int x, int y, int max, int cnt) {if (cache[x][y][max + 1][cnt] != -1) return cache[x][y][max + 1][cnt];if (x == n || y == m || cnt > k) return 0;int cur = data[x][y];int ans = 0;if (x == n - 1 && y == m - 1) {if (cnt == k || (cnt == k - 1 && cur > max)) return 1;return ans;}if (cur > max) {ans += dfs(x, y + 1, cur, cnt + 1);ans += dfs(x + 1, y, cur, cnt + 1);}ans += dfs(x, y + 1, max, cnt);ans += dfs(x + 1, y, max, cnt);cache[x][y][max + 1][cnt] = ans % MOD;return ans;} }解法二:滿分代碼
package provincialGames_05_2014_JavaB;import java.util.Scanner;public class A09_地宮取寶 {public static int n, m, k;public static long MOD = 1000000007;public static int[][] map;public static long[][][][] visited = new long[51][51][102][13];public static long dfs(int x, int y, int num, int max) {if (visited[x][y][num][max + 1] != -1)return visited[x][y][num][max + 1];if (x == n - 1 && y == m - 1) {if (num == k)visited[x][y][num][max + 1] = 1;else if (num == k - 1 && max < map[x][y])visited[x][y][num][max + 1] = 1;elsevisited[x][y][num][max + 1] = 0;return visited[x][y][num][max + 1];}long result = 0;if (x + 1 < n) { // 向下移動一步if (max < map[x][y]) {result += dfs(x + 1, y, num + 1, map[x][y]);result %= MOD;}result += dfs(x + 1, y, num, max);result %= MOD;}if (y + 1 < m) { // 向右移動一步if (max < map[x][y]) {result += dfs(x, y + 1, num + 1, map[x][y]);result %= MOD;}result += dfs(x, y + 1, num, max);result %= MOD;}return visited[x][y][num][max + 1] = result % MOD;}public static void main(String[] args) {Scanner in = new Scanner(System.in);n = in.nextInt();m = in.nextInt();k = in.nextInt();map = new int[n][m];for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)map[i][j] = in.nextInt();for (int i = 0; i < 51; i++)for (int j = 0; j < 51; j++)for (int x = 0; x < 102; x++)for (int y = 0; y < 13; y++)visited[i][j][x][y] = -1;long ans = dfs(0, 0, 0, -1);System.out.println(visited[0][0][0][0]);} } /**import java.util.Scanner;public class Main {public static int n, m, k;public static long MOD = 1000000007;public static int[][] map;public static long[][][][] visited = new long[51][51][102][13];public long dfs(int x, int y, int num, int max) {if(visited[x][y][num][max + 1] != -1)return visited[x][y][num][max + 1];if(x == n - 1 && y == m - 1) {if(num == k)visited[x][y][num][max + 1] = 1;else if(num == k - 1 && max < map[x][y])visited[x][y][num][max + 1] = 1;else visited[x][y][num][max + 1] = 0;return visited[x][y][num][max + 1];}long result = 0;if(x + 1 < n) { //向下移動一步if(max < map[x][y]) {result += dfs(x + 1, y, num + 1, map[x][y]);result %= MOD;}result += dfs(x + 1, y, num, max);result %= MOD;}if(y + 1 < m) { //向右移動一步if(max < map[x][y]) {result += dfs(x, y + 1, num + 1, map[x][y]);result %= MOD;}result += dfs(x, y + 1, num, max);result %= MOD;}return visited[x][y][num][max + 1] = result % MOD;}public static void main(String[] args) {Main test = new Main();Scanner in = new Scanner(System.in);n = in.nextInt();m = in.nextInt();k = in.nextInt();map = new int[n][m];for(int i = 0;i < n;i++)for(int j = 0;j < m;j++)map[i][j] = in.nextInt();for(int i = 0;i < 51;i++)for(int j = 0;j < 51;j++)for(int x = 0;x < 102;x++)for(int y = 0;y < 13;y++)visited[i][j][x][y] = -1;test.dfs(0, 0, 0, -1);System.out.println(visited[0][0][0][0]);}}*/解法三:42分
package provincialGames_05_2014_JavaB;import java.util.Scanner;public class A09_地宮取寶42points { // 非記憶型數組private static int n, m, k; // private static int m; // private static int k;private static final int MOD = 1000000007;static int[][] data;public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();m = sc.nextInt();k = sc.nextInt();data = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {data[i][j] = sc.nextInt();}}long ans = dfs(0, 0, -1, 0);System.out.println(ans);}// x y: 當前所處位置[0, n-1\m-1]; max: 所遇到的最大值; cnt: 已取寶貝的數量private static long dfs(int x, int y, int max, int cnt) {if (x == n || y == m || cnt > k) // 越界 返回 0return 0;int cur = data[x][y]; // 所處格子中的寶貝價值int ans = 0;if (x == n - 1 && y == m - 1) {if (cnt == k || (cnt == k - 1 && cur > max))// cnt == k - 1, 再加上max這個值, cnt 剛好 == kreturn 1;return ans;}// 如果那個格子中的寶貝價值比小明手中任意寶貝價值都大, 小明就可以拿起它if (cur > max) {ans += dfs(x, y + 1, cur, cnt + 1);ans += dfs(x + 1, y, cur, cnt + 1);}// 當然,也可以不拿ans += dfs(x, y + 1, max, cnt);ans += dfs(x + 1, y, max, cnt);return ans % MOD;} }解法四:57分
package provincialGames_05_2014_JavaB;import java.util.Scanner;public class A09_地宮取寶57points { // 記憶型數組private static int n;private static int m;private static int k;private static final int MOD = 1000000007;static int[][] data;static long[][][][] cache = new long[51][51][14][14]; // 四維public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();m = sc.nextInt();k = sc.nextInt();data = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {data[i][j] = sc.nextInt();}}for (int i = 0; i < 51; i++) { // 初始化for (int j = 0; j < 51; j++) {for (int l = 0; l < 14; l++) {for (int o = 0; o < 14; o++) {cache[i][j][l][o] = -1;}}}}long ans = dfs(0, 0, -1, 0);System.out.println(ans);}private static long dfs(int x, int y, int max, int cnt) {// max == -1, max + 1 防止 數組越界if (cache[x][y][max + 1][cnt] != -1) // 曾經有記錄 寫緩存return cache[x][y][max + 1][cnt];if (x == n || y == m || cnt > k)return 0;int cur = data[x][y];int ans = 0;if (x == n - 1 && y == m - 1) {if (cnt == k || (cnt == k - 1 && cur > max))return 1;return ans;}if (cur > max) {ans += dfs(x, y + 1, cur, cnt + 1);ans += dfs(x + 1, y, cur, cnt + 1);}ans += dfs(x, y + 1, max, cnt);ans += dfs(x + 1, y, max, cnt);cache[x][y][max + 1][cnt] = ans % MOD; // 取緩存return ans;} }十、矩陣翻硬幣
標題:矩陣翻硬幣
? ? 小明先把硬幣擺成了一個 n 行 m 列的矩陣。
? ? 隨后,小明對每一個硬幣分別進行一次 Q 操作。
? ? 對第x行第y列的硬幣進行 Q 操作的定義:將所有第 i*x 行,第 j*y 列的硬幣進行翻轉。
? ? 其中i和j為任意使操作可行的正整數,行號和列號都是從1開始。
? ? 當小明對所有硬幣都進行了一次 Q 操作后,他發現了一個奇跡——所有硬幣均為正面朝上。
? ? 小明想知道最開始有多少枚硬幣是反面朝上的。于是,他向他的好朋友小M尋求幫助。
? ? 聰明的小M告訴小明,只需要對所有硬幣再進行一次Q操作,即可恢復到最開始的狀態。然而小明很懶,不愿意照做。于是小明希望你給出他更好的方法。幫他計算出答案。
【數據格式】
? ? 輸入數據包含一行,兩個正整數 n m,含義見題目描述。
? ? 輸出一個正整數,表示最開始有多少枚硬幣是反面朝上的。
【樣例輸入】
2 3
【樣例輸出】
1
【數據規模】
對于10%的數據,n、m <= 10^3;
對于20%的數據,n、m <= 10^7;
對于40%的數據,n、m <= 10^15;
對于100%的數據,n、m <= 10^1000(10的1000次方)。
資源約定:
峰值內存消耗(含虛擬機) < 256M
CPU消耗 ?< 2000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多余內容。
所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效代碼處理。
//第x行第y列被翻動的總次數?
//考慮第1行,第y列,y有多少真因子,就會被翻動多少次,而所有的y中,只有平方數的真因子個數為奇數(約數總是成對出現的)
//考慮第1列,第x行,x有多少真因子,就會被翻動多少次,而所有的x中,只有平方數的真因子個數為奇數
//x,y硬幣被翻動的次數=x真因子個數*y真因子個數,只有奇數*奇數=奇數,所以,若要x,y為反面,必須x,y都是平方數
//因此,反面硬幣總數=m中的平方數的個數*n中平方數的個數
//那么在m中有多少個平方數呢?答案是sqrt(m)向下取整個,如9內有三個平方數1,4,9;16里面有4個平方數1,4,9,16;25內有5個平方數
//因此此題等價于求sqrt(m)*sqrt(n),那么怎么對一個很大的數開平方呢?
//假設一個數的長度為length,其平方根的長度為length/2(偶數)或者length/2+1(奇數)
//我們可以從高位不停地試探,每一個取平方后恰好不超過目標平方數的值
字符、字符串 與 BigInteger 相互轉化
package Z;import java.math.BigInteger; import java.util.Arrays;public class BigIntegerStr { // 字符、字符串 與 BigInteger 相互轉化public static void main(String[] args) {char[] strArr = new char[11];Arrays.fill(strArr, '1');System.out.println(Arrays.toString(strArr));System.out.println("1、字符數組 轉 BigInteger:");BigInteger one = new BigInteger(String.valueOf(strArr)); // char數組->字符串System.out.println(one);System.out.println("2、String 轉 BigInteger:");String str = "12";BigInteger two = new BigInteger(str);System.out.println(two.pow(2));System.out.println("3、BigInteger 轉 字符串:");BigInteger three = new BigInteger("100");String threeStr = three + "";System.out.println(threeStr);System.out.println("4、BigInteger 轉 字符串:");BigInteger four = new BigInteger("500");char fourChar[] = (four + "").toCharArray();System.out.println(fourChar);}}小結
01 武功秘籍 書的構造方式,思維題
02 切面條 發現規律,思維題
03 猜字母 數組中元素的挪動和擠壓
04 大衍數列 考察奇偶數判斷
05 圓周率 細心,極限思維
06 奇怪的分式 枚舉abcd,分數運算,最大公約數
07 撲克排序 帶重復元素的全排列
08 分糖果 模擬
**09 地宮取寶 搜索->記憶型遞歸,因為子問題重復求解
****10 矩陣翻硬幣 數學;字符,字符串,BigInteger的互相轉化
總結
以上是生活随笔為你收集整理的2014年 第5届 蓝桥杯 Java B组 省赛解析及总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 01【两数之和】【Le
- 下一篇: Java20-day11【实现多线程(进