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

題目及解析以下:java

題目大體介紹:c++

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

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

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

 

 

第一題 世紀末的星期瀏覽器

曾有邪教稱1999年12月31日是世界末日。固然該謠言已經不攻自破。還有人稱從此的某個世紀末的12月31日,若是是星期一則會....ide

有趣的是,任何一個世紀末的年份的12月31日都不多是星期一!! 因而,「謠言製造商」又修改成星期日......spa

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

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

這個題可使用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 }

 

 

第十題  連號區間數

相關文章
相關標籤/搜索