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 }

 

 

第十题  连号区间数

相关文章
相关标签/搜索