2013年第四屆藍橋杯JavaB組省賽試題解析


題目及解析如下:

題目大致介紹:

第一題到第四題是結果填空,方法不限只要得到最后結果就行

第五題和第六題是代碼填空題,主要考察算法基本功和編程基本功

第七題到第十題是編程題,要求編程解決問題

 

 

第一題 世紀末的星期

曾有邪教稱1999年12月31日是世界末日。當然該謠言已經不攻自破。還有人稱今后的某個世紀末的12月31日,如果是星期一則會....

有趣的是,任何一個世紀末的年份的12月31日都不可能是星期一!! 於是,“謠言制造商”又修改為星期日......

1999年的12月31日是星期五,請問:未來哪一個離我們最近的一個世紀末年(即xx99年)的12月31日正好是星期天(即星期日)?

請回答該年份(只寫這個4位整數,不要寫12月31等多余信息)

這個題可以使用Java中的Calendar類來做,考試的時候直接看API就行,平時了解一下就行了,代碼如下:

 1 import java.util.Calendar;
 2 
 3 // 2299
 4 public class t1 {
 5     
 6     public static void main(String[] args) {
 7         Calendar canlendar = Calendar.getInstance();
 8         for(int year = 1999; year < 5000; year+=100) {
 9             canlendar.set(Calendar.YEAR, year);
10             canlendar.set(Calendar.MONTH, 11);    // 12月
11             canlendar.set(Calendar.DAY_OF_MONTH, 31);
12             System.out.println(canlendar.toInstant());                    // 輸出年月日
13             System.out.println(canlendar.get(Calendar.DAY_OF_WEEK));    // 輸出星期幾
14             if(canlendar.get(Calendar.DAY_OF_WEEK) == 1) {
15                 // 注: 1表示星期日
16                 System.out.println(year);
17                 break;
18             }
19         }
20     }
21     
22 }

 

 

第二題 馬虎的算式

小明是個急性子上小學的時候經常把老師寫在黑板上的題目抄錯了。 有一次老師出的題目是36 x 495 = ? 他卻給抄成了396 x 45 = ? 

但結果卻很戲劇性他的答案竟然是對的  因為 36 * 495 = 396 * 45 = 17820   類似這樣的巧合情況可能還有很多比如27 * 594 = 297 * 54 

假設 a b c d e 代表1~9不同的5個數字注意是各不相同的數字且不含0   能滿足形如ab * cde = adb * ce 這樣的算式一共有多少種呢

一看就知道應該是用暴力法,5層for循環再加一個check就行:

 1 // 142
 2 
 3 public class t2 {
 4 
 5     public static void main(String[] args) {
 6         int res = 0;
 7         for (int a = 1; a <= 9; a++) {
 8             for (int b = 1; b <= 9; b++) {
 9                 for (int c = 1; c <= 9; c++) {
10                     for (int d = 1; d <= 9; d++) {
11                         for (int e = 1; e <= 9; e++) {
12                             if (b != a && c != b && c != a && d != c && d != b && d != a && e != d && e != c && e != b
13                                     && e != a) {
14                                 if (((a * 10 + b) * (c * 100 + d * 10 + e)) == ((a * 100 + d * 10 + b) * (c * 10 + e))) {
15                                     res++;
16                                 }
17                             }
18                         }
19                     }
20                 }
21             }
22         }
23 
24         System.out.println(res);
25     }
26 
27 }

注:這種題記得輸出結果進行驗證一下!細節很重要!

 

 

第三題 振興中華

小明參加了學校的趣味運動會,其中的一個項目是:跳格子 地上畫着一些格子,每個格子里寫一個字,如下所示:(也可參見p1.jpg)

 從我做起振
 我做起振興
 做起振興中
 起振興中華

比賽時,先站在左上角的寫着“從”字的格子里,可以橫向或縱向跳到相鄰的格子里,但不能跳到對角的格子或其它位置。一直要跳到“華”字結束。

要求跳過的路線剛好構成“從我做起振興中華”這句話。

請你幫助小明算一算他一共有多少種可能的跳躍路線呢?

答案是一個整數,請通過瀏覽器直接提交該數字。注意:不要提交解答過程,或其它輔助說明類的內容

用遞歸,代碼如下:

 1 // 35
 2 
 3 public class t3 {
 4 
 5     public static int f(int r, int c) {
 6         if (r == 3 || c == 4) {
 7             return 1;
 8         }
 9         return f(r + 1, c) + f(r, c + 1);
10     }
11 
12     public static void main(String[] args) {
13         System.out.println(f(0, 0));
14     }
15 
16 }

 

 

第四題 黃金連分數

黃金分割數0.61803... 是個無理數,這個常數十分重要,在許多工程問題中會出現。有時需要把這個數字求得很精確。
言歸正傳,我們如何求得黃金分割數的盡可能精確的值呢?有許多方法。
比較簡單的一種是用連分數:


                            1
    黃金數 = ---------------------
                                  1
                      1 + -----------------
                                          1
                               1 + -------------
                                             1
                                    1 + ---------
                                           1 + ...

這個連分數計算的“層數”越多,它的值越接近黃金分割數。
請你利用這一特性,求出黃金分割數的足夠精確值,要求四舍五入到小數點后100位。
小數點后3位的值為:0.618
小數點后4位的值為:0.6180
小數點后5位的值為:0.61803
小數點后7位的值為:0.6180340
(注意尾部的0,不能忽略)
你的任務是:寫出精確到小數點后100位精度的黃金分割值。
注意:尾數的四舍五入! 尾數是0也要保留!
顯然答案是一個小數,其小數點后有100位數字,請通過瀏覽器直接提交該數字。
注意:不要提交解答過程,或其它輔助說明類的內容。

解題思路:

可以化為求斐波那契數列相鄰兩項的比值:

但是注意直接用double精度會不夠,因此我們可以使用BigInteger類和BigDecimal類:

 1 import java.math.BigDecimal;
 2 import java.math.BigInteger;
 3 
 4 public class t4 {
 5 
 6     public static void main(String[] args) {
 7         BigInteger a = BigInteger.ONE;
 8         BigInteger b = BigInteger.ONE;
 9         for (int i = 3; i < 500; i++) {
10             BigInteger t = b;
11             b = a.add(b);
12             a = t;
13         }
14         BigDecimal divide = new BigDecimal(a, 110).divide(new BigDecimal(b, 110), BigDecimal.ROUND_HALF_DOWN);
15         System.out.println(divide.toPlainString().substring(0, 103));
16     }
17     
18     // 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244969233401224637257135
19     // 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
20     // 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
21     
22     // answer:
23     // 0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375
24     
25 }

 

 

第五題  有理數類

 1 // 有理數類
 2 
 3 // 有理數就是可以表示為兩個整數的比值的數字。一般情況下,我們用近似的小數表示。但有些時候,
 4 // 不允許出現誤差,必須用兩個整數來表示一個有理數。
 5 // 這時,我們可以建立一個“有理數類”,下面的代碼初步實現了這個目標。為了簡明,它只提供了
 6 // 加法和乘法運算。
 7 
 8 // 使用該類的示例:
 9 // Rational a = new Rational(1,3);
10 // Rational b = new Rational(1,6);
11 // Rational c = a.add(b);
12 // System.out.println(a + "+" + b + "=" + c);
13 
14 public class t5 {
15     static class Rational {
16         private long ra;
17         private long rb;
18 
19         private long gcd(long a, long b) {
20             if (b == 0)
21                 return a;
22             return gcd(b, a % b);
23         }
24 
25         public Rational(long a, long b) {
26             ra = a;
27             rb = b;
28             long k = gcd(ra, rb);
29             if (k > 1) { // 需要約分
30                 ra /= k;
31                 rb /= k;
32             }
33         }
34 
35         // 加法
36         public Rational add(Rational x) {
37             // return ________________________________________;  //填空位置
38             return new Rational(ra * x.rb + rb * x.ra, rb * x.rb);
39         }
40 
41         // 乘法
42         public Rational mul(Rational x) {
43             return new Rational(ra * x.ra, rb * x.rb);
44         }
45 
46         public String toString() {
47             if (rb == 1)
48                 return "" + ra;
49             return ra + "/" + rb;
50         }
51     }
52 
53     public static void main(String[] args) {
54         Rational a = new Rational(1, 3);
55         Rational b = new Rational(1, 6);
56         Rational c = a.add(b);
57         System.out.println(a + "+" + b + "=" + c);
58 
59         Rational a1 = new Rational(1, 3);
60         Rational b1 = new Rational(1, 3);
61         Rational c1 = a.add(b1);
62         System.out.println(a1 + "+" + b1 + "=" + c1);
63     }
64 
65 }

 

 

第六題  三部排序

 1 // 三部排序
 2 // 對一個整型數組中的數字進行分類排序:使得負數都靠左端,正數都靠右端,0在中部。
 3 // 注意問題的特點是:
 4 // 負數區域和正數區域內並不要求有序。可以利用這個特點通過1次線性掃描就結束戰斗!!
 5 
 6 public class t6 {
 7     static void sort(int[] x)
 8     {
 9         int p = 0;
10         int left = 0;
11         int right = x.length-1;
12         
13         while(p<=right){
14             if(x[p]<0){
15                 int t = x[left];
16                 x[left] = x[p];
17                 x[p] = t;
18                 left++;
19                 p++;
20             }
21             else if(x[p]>0){
22                 int t = x[right];
23                 x[right] = x[p];
24                 x[p] = t;
25                 right--;            
26             }
27             else{
28                 p++;  //代碼填空位置
29             }
30         }
31     }
32 }

 

 

第七題  錯誤票據

思路:

處理輸入比較麻煩,可以用ArrayList來動態添加來保存輸入的數,然后先用sort排序一下,從小到大排,排完后枚舉判斷即可

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.Scanner;
 4 
 5 // 錯誤票據
 6 //    某涉密單位下發了某種票據,並要在年終全部收回。
 7 //
 8 //    每張票據有唯一的ID號。全年所有票據的ID號是連續的,但ID的開始數碼是隨機選定的。
 9 //
10 //    因為工作人員疏忽,在錄入ID號的時候發生了一處錯誤,造成了某個ID斷號,另外一個ID重號。
11 //
12 //    你的任務是通過編程,找出斷號的ID和重號的ID。
13 //
14 //    假設斷號不可能發生在最大和最小號。
15 //
16 //    要求程序首先輸入一個整數N(N<100)表示后面數據行數。
17 //   接着讀入N行數據。
18 //   每行數據長度不等,是用空格分開的若干個(不大於100個)正整數(不大於100000)
19 //   每個整數代表一個ID號。
20 //
21 //   要求程序輸出1行,含兩個整數m n,用空格分隔。
22 //   其中,m表示斷號ID,n表示重號ID
23 //
24 //
25 //
26 //例如:
27 //用戶輸入:
28 //2
29 //5 6 8 11 9 
30 //10 12 9
31 //則程序輸出:
32 //7 9
33 //
34 //再例如:
35 //用戶輸入:
36 //6
37 //164 178 108 109 180 155 141 159 104 182 179 118 137 184 115 124 125 129 168 196
38 //172 189 127 107 112 192 103 131 133 169 158 
39 //128 102 110 148 139 157 140 195 197
40 //185 152 135 106 123 173 122 136 174 191 145 116 151 143 175 120 161 134 162 190
41 //149 138 142 146 199 126 165 156 153 193 144 166 170 121 171 132 101 194 187 188
42 //113 130 176 154 177 120 117 150 114 183 186 181 100 163 160 167 147 198 111 119
43 //則程序輸出:
44 //105 120
45 
46 public class t7 {
47 
48     private static Scanner input;
49 
50     public static void main(String[] args) {
51         input = new Scanner(System.in);
52         ArrayList list = new ArrayList<Integer>();
53 
54         System.out.println(":  ");
55 
56         int N = input.nextInt();
57         input.nextLine(); // 去掉整數后面的換行符
58         for (int i = 0; i < N; i++) {
59             String line = input.nextLine();
60             String[] split = line.split(" ");
61             for (int j = 0; j < split.length; j++) {
62                 list.add(Integer.parseInt(split[j]));
63             }
64         }
65 
66         // System.out.println(list.size());
67         
68         Collections.sort(list); // 對集合進行排序
69         int a = 0, b = 0; // a接收斷號的 b接收重號的
70         for (int i = 1; i < list.size(); i++) {
71             int cur = (int) (list.get(i));
72             int pre = (int) (list.get(i - 1));
73             if (cur - pre == 2) {
74                 a = (int)(list.get(i)) - 1;
75             }
76             if (cur - pre == 0) {
77                 b = (int)(list.get(i));
78             }
79         }
80         System.out.println(a + " " + b);
81     }
82 
83 }

 

 

第八題  幸運數  =》 太難 看不懂 直接放棄

 

第九題  帶分數

代碼如下:

 1 import java.util.Scanner;
 2 
 3 // 問題描述
 4 // 100 可以表示為帶分數的形式:100 = 3 + 69258 / 714。
 5 // 還可以表示為:100 = 82 + 3546 / 197。
 6 // 注意特征:帶分數中,數字1~9分別出現且只出現一次(不包含0)。
 7 //
 8 // 類似這樣的帶分數,100 有 11 種表示法。
 9 //
10 // 輸入格式
11 // 從標准輸入讀入一個正整數N (N<1000*1000)
12 //
13 // 輸出格式
14 // 程序輸出該數字用數碼1~9不重復不遺漏地組成帶分數表示的全部種數。
15 //
16 // 注意:不要求輸出每個表示,只統計有多少表示法!
17 //
18 // 樣例輸入1
19 // 100 
20 // 樣例輸出1
21 // 11
22 // 樣例輸入2
23 // 105
24 // 樣例輸出2
25 // 6
26 
27 public class t9 {
28     public static int res = 0;
29     public static int N = 0;
30     private static Scanner input;
31 
32     public static void main(String[] args) {
33         input = new Scanner(System.in);
34         System.out.println(); // 提交代碼的時候注釋
35         N = input.nextInt();
36         int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
37         f(0, arr);
38         System.out.println(res);
39     }
40 
41     // i: 確認某一個全排列的第k位
42     private static void f(int k, int[] arr) {
43         if (k == 9) {
44             check(arr);
45             return;
46         }
47         for (int i = k; i < arr.length; i++) {
48             int temp = arr[k];
49             arr[k] = arr[i];
50             arr[i] = temp;
51             f(k + 1, arr); // 選定第k位移交下一層確認k+1位
52             temp = arr[k];
53             arr[k] = arr[i];
54             arr[i] = temp;
55         }
56 
57     }
58 
59     // 枚舉加號和乘號的位置
60     private static void check(int[] arr) {
61         for (int i = 1; i <= 7; i++) {
62             // 遍歷生成第一個數
63             int num1 = toInt(arr, 0, i);
64             if (num1 >= N) {
65                 return;
66             }
67             for (int j = 1; j <= 8 - i; j++) {
68                 // 遍歷生成第二個、第三個數
69                 int num2 = toInt(arr, i, j);
70                 int num3 = toInt(arr, i + j, 9 - i - j);
71                 if (num2 % num3 == 0 && num1 + num2 / num3 == N) {
72                     res++;
73                 }
74             }
75         }
76 
77     }
78 
79     private static int toInt(int[] arr, int pos, int len) {
80         // 將數組中的數轉換成整數
81         int t = 1;
82         int ans = 0;
83         for (int i = pos + len - 1; i >= pos; i--) {
84             ans += arr[i] * t;
85             t *= 10;
86         }
87 
88         return ans;
89     }
90 
91 }

 

 

第十題  連號區間數

 


免責聲明!

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



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