第九届蓝桥杯真题解析JavaC组
前言
以下是我做第九届蓝桥杯真题时的一些收获,希望对你们有帮助。
提示:以下是本篇文章正文内容,下面案例可供参考
A、哪天回家
问题描述:
小明被不明势力劫持。后被扔到x星站再无问津。小明得知每天都有飞船飞往地球,但需要108元的船票,而他却身无分文。
他决定在x星战打工。好心的老板答应包食宿,第1天给他1元钱。
并且,以后的每一天都比前一天多2元钱,直到他有足够的钱买票。
请计算一下,小明在第几天就能凑够108元,返回地球。
计算出需要多少天才能完成
这道题根本不难,只需要使用到一次循环即可。
代码如下(示例):
public class Nine1_哪天回家 {
public static void main(String[] args) {
//统计天数
int days = 0;
//统计钱数
int moneySum = 0;
//记录第一天的钱数
int n = 1;
while(moneySum < 108) {
moneySum += n;
n += 2;
days++;
}
System.out.println("需要" + days + "天");
}
}
B.猴子分香蕉
问题描述:
5只猴子是好朋友,在海边的椰子树上睡着了。这期间,有商船把一大堆香蕉忘记在沙滩上离去。
第1只猴子醒来,把香蕉均分成5堆,还剩下1个,就吃掉并把自己的一份藏起来继续睡觉。
第2只猴子醒来,重新把香蕉均分成5堆,还剩下2个,就吃掉并把自己的一份藏起来继续睡觉。
第3只猴子醒来,重新把香蕉均分成5堆,还剩下3个,就吃掉并把自己的一份藏起来继续睡觉。
第4只猴子醒来,重新把香蕉均分成5堆,还剩下4个,就吃掉并把自己的一份藏起来继续睡觉。
第5只猴子醒来,重新把香蕉均分成5堆,哈哈,正好不剩!
请计算一开始最少有多少个香蕉。
这道题直接暴力破解即可。
代码如下(示例):
public class Nine2_猴子分香蕉 {
public static void main(String[] args) {
//使用i来表示香蕉的数量
for(int i = 1; ; i++) {
//创建一个变量用来代替i的值。因为i的值是会发生改变的
int sum = i;
//进行判断
if(sum % 5 == 1) {
sum = sum - 1 - sum / 5;//分成五堆并吃了剩下的,然后再把自己的那一份藏起来
if(sum % 5 == 2) {
sum = sum - 2 - sum / 5;//分成五堆并吃了剩下的,然后再把自己的那一份藏起来
if(sum % 5 == 3) {
sum = sum - 3 - sum / 5;//分成五堆并吃了剩下的,然后再把自己的那一份藏起来
if(sum % 5 == 4) {
sum = sum - 4 - sum / 5;//分成五堆并吃了剩下的,然后再把自己的那一份藏起来
//设置出口
if(sum % 5 == 0 && sum != 0) {//香蕉的数量不可能为0
System.out.println("一开始最少有" + i + "个香蕉");
break;
}
}
}
}
}
}
}
}
C.字母阵列
问题描述:
仔细寻找,会发现:在下面的8x8的方阵中,隐藏着字母序列:“LANQIAO”。
SLANQIAO
ZOEXCCGB
MOAYWKHI
BCCIPLJQ
SLANQIAO
RSFWFNYA
XIFZVWAL
COAIQNAL
我们约定: 序列可以水平,垂直,或者是斜向;
并且走向不限(实际上就是有一共8种方向)。
上图中一共有4个满足要求的串。
下面有一个更大的(100x100)的字母方阵。
你能算出其中隐藏了多少个“LANQIAO”吗?
请提交一个整数,不要填写任何多余的内容。
这道题难度也没有那么大,只需要分析对方向即可。
代码如下(示例):
import java.util.Arrays;
import java.util.Scanner;
public class Nine3_字母阵列 {
//记录最终的总个数
static int max;
/**
* 思路:首先找出L,再进行判断后面的
* @param args
*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine();
//定义二维char数组 存储字符数据
char[][] chars = new char[n][];
for (int i = 0; i < n; i++) {
chars[i] = scanner.nextLine().toCharArray();
// System.out.println(Arrays.toString(chars[i]));
}
scanner.close();
for (int i = 0; i < chars.length; i++) {
for (int j = 0; j < chars[i].length; j++) {
//先寻找到L字符,可以开始向八个方向去探
if(chars[i][j] == 'L') {
//双重循环分别给横纵坐标一个增量 _x,_y
for (int _x = -1; _x < 2; _x++) {
for (int _y = -1; _y < 2; _y++) {
//保证不能越界
if(_x == 0 && _y == 0) {
continue;
}
if(i + _x >= 0 && i + _x < chars.length && j + _y >= 0 && j + _y < chars[i].length) {
//开始尝试走出一步
dfs(chars, i + _x, j + _y, _x, _y, 0);
}
}
}
}
}
}
System.out.println(max);
}
//创建一个target用来对照相应位置上的字符是否符号要求
static char[] target = {'A', 'N', 'Q', 'I', 'A', 'O'};
private static void dfs(char[][] chars, int x, int y, int _x, int _y, int cur) {
//如果不符合要求,那么就退出,尝试另外一个方向
if(chars[x][y] != target[cur]) {
return;
}
//当程序执行到这里 说明符合要求 如果已经检索到target的第六个元素,说明找到一行“蓝桥”
if(cur == 5) {
max++;//计数
return;
}
//否则没有完整的找到一行LANQIAO
if(x + _x >= 0 && x + _x < chars.length && y + _y >= 0 && y + _y < chars[0].length) {
//注意:这次并不能向八个方向来搜索 要延续上一次的方向也就是你横纵坐标的增量不能改变
dfs(chars, x + _x, y + _y, _x, _y, cur + 1);
}
}
}
D.第几个幸运数
问题描述:
到x星球旅行的游客都被发给一个整数,作为游客编号。 x星的国王有个怪癖,他只喜欢数字3,5和7。 国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。
我们来看前10个幸运数字是:
3 5 7 9 15 21 25 27 35 45
因而第11个幸运数字是:49
(7,9,15)是3分别乘以3,5,7的
(15,25,35)是5分别乘以3,5,7的
(21,35,49)是7分别乘以3,5,7的
小明领到了一个幸运数字 59084709587505,他去领奖的时候,人家要求他准确地说出这是第几个幸运数字,否则领不到奖品。
请你帮小明计算一下,59084709587505是第几个幸运数字。
需要提交的是一个整数,请不要填写任何多余内容。
这道题有点难度了。
代码如下(示例):
import java.util.TreeSet;
public class Nine4_第几个幸运数 {
final static long Max = 59084709587505L;
public static void inits() {
long t = 1;
//将3,5,7这三个因子存储到数组中
int[] divisor = {3,5,7};
//创建一个TreeSet集合
TreeSet<Long> s = new TreeSet<Long>();
while(true) {
for (int i = 0; i < divisor.length; i++) {
long tt = divisor[i] * t;
if(tt <= Max) {
s.add(tt);
}
}
//返回最小的元素在这套严格大于给定的元素,或 null如果没有这样的元素。
t = s.higher(t);
if(t >= Max) {
break;
}
}
System.out.println(s.size());
}
public static void print() {
long count = 0;
//返回将第一个参数的值提高到第二个参数的功率。
for (long i = 0; Math.pow(3, i) < Max; i++) {
for (long j = 0; Math.pow(5, j) < Max; j++) {
for (long k = 0; Math.pow(7, k) < Max; k++) {
if(Math.pow(3, i) * Math.pow(5, j) * Math.pow(7, k) < Max) {
count++;
}
}
}
}
System.out.println(count);
}
public static void main(String[] args) {
inits();
print();
}
}
E.书号验证
问题描述:
2004年起,国际ISBN中心出版了《13位国际标准书号指南》。
原有10位书号前加978作为商品分类标识;校验规则也改变。
校验位的加权算法与10位ISBN的算法不同,具体算法是:
用1分别乘ISBN的前12位中的奇数位(从左边开始数起),用3乘以偶数位,
乘积之和以10为模,10与模值的差值再对10取模(即取个位的数字)即可得到校验位的值,其值范围应该为0~9。
下面的程序实现了该算法,请仔细阅读源码,填写缺失的部分。
public class A
{
static boolean f(String s){
int k = 1;
int sum = 0;
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if(c == '-' || c == ' ') continue;
sum += ______________________________; //填空
k++;
if(k > 12) break;
}
return s.charAt(s.length() - 1) - '0' == (10 - sum % 10) % 10;
}
public static void main(String[] args){
System.out.println(f("978-7-301-04815-3"));
System.out.println(f("978-7-115-38821-6"));
}
}
请仔细分析源码,并完成划线部分缺少的代码。
注意:只提交缺少的代码,不要提交已有的代码和符号。也不要提交说明性文字。
答案是:sum += (c - ‘0’) * (k % 2 == 0 ? 3 : 1);
F.打印大X
问题描述:
如下的程序目的是在控制台打印输出大X。
可以控制两个参数:图形的高度,以及笔宽。
用程序中的测试数据输出效果:
(如果显示有问题,可以参看p1.png)
高度=15, 笔宽=3
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
*****
***
*****
*** ***
*** ***
*** ***
*** ***
*** ***
*** ***
高度=8, 笔宽=5
***** *****
**********
********
******
******
********
**********
***** *****
请仔细分析程序流程,填写缺失的代码。
public class A{
static void f(int h, int w){
System.out.println(String.format("高度=%d, 笔宽=%d",h,w));
int a1 = 0;
int a2 = h - 1;
for(int k = 0; k < h; k++){
int p = Math.min(a1,a2);
int q = Math.max(a1 + w,a2 + w);
for(int i = 0; i < p; i++) System.out.print(" ");
if(q-p < w*2){
____________________________________________ ; //填空
}
else{
for(int i = 0; i < w; i++) System.out.print("*");
for(int i = 0; i < q-p-w*2; i++) System.out.print(" ");
for(int i =0; i < w; i++) System.out.print("*");
}
System.out.println();
a1++;
a2--;
}
}
public static void main(String[] args){
f(15,3);
f(8,5);
}
}
注意:只提交缺少的代码,不要提交已有的代码和符号。也不要提交说明性文字。
答案:for(int i = 0; i < q - p; i++) System.out.print("*");
G.缩位求和
问题描述:
在电子计算机普及以前,人们经常用一个粗略的方法来验算四则运算是否正确。
比如:248 * 15 = 3720
把乘数和被乘数分别逐位求和,如果是多位数再逐位求和,直到是1位数,得
2 + 4 + 8 = 14 ==> 1 + 4 = 5;
1 + 5 = 6
5 * 6
而结果逐位求和为 3
5 * 6 的结果逐位求和与3符合,说明正确的可能性很大!!(不能排除错误)
请你写一个计算机程序,对给定的字符串逐位求和:
输入为一个由数字组成的串,表示n位数(n<1000);
输出为一位数,表示反复逐位求和的结果。
例如:
输入:
35379
程序应该输出:
9
再例如:
输入:
7583676109608471656473500295825
程序应该输出:
1
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
注意:
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
这道题大致的意思就是把输入的一串数拆开,个个相加,最后的结果 变成新的字符串,用于下次循环,再拆开相加,直到最后只有一个数字。 代码如下(示例):
import java.util.Scanner;
public class Nine7_缩位求和 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String temp = scanner.next();
scanner.close();
while(temp.length() > 1) {
int sum = 0;
for (int i = 0; i < temp.length(); i++) {
sum += temp.charAt(i) - '0';
}
temp = String.valueOf(sum);
}
System.out.println(Integer.parseInt(temp));
}
}
H.等腰三角形
问题描述:
本题目要求你在控制台输出一个由数字组成的等腰三角形。 具体的步骤是: 1. 先用1,2,3,...的自然数拼一个足够长的串 2. 用这个串填充三角形的三条边。从上方顶点开始,逆时针填充。 比如,当三角形高度是8时:
1
2 1
3 8
4 1
5 7
6 1
7 6
891011121314151
显示不正确时,参看:p1.png
输入,一个正整数n(3<n<300),表示三角形的高度
输出,用数字填充的等腰三角形。
为了便于测评,我们要求空格一律用"."代替。
例如:
输入:
5
程序应该输出:
....1
...2.1
..3...2
.4.....1
567891011
再例如:
输入:
10
程序应该输出:
.........1
........2.2
.......3...2
......4.....2
.....5.......1
....6.........2
...7...........0
..8.............2
.9...............9
1011121314151617181
再例如:
输入:
15
程序应该输出:
..............1
.............2.3
............3...2
...........4.....3
..........5.......1
.........6.........3
........7...........0
.......8.............3
......9...............9
.....1.................2
....0...................8
...1.....................2
..1.......................7
.1.........................2
21314151617181920212223242526
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
注意:
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
这道题说难也不难,只要按照题目要求一步步来即可。
思路:
1、先明确自己所需的数字
2、3<n<300 所以第一行必定是(n-1)个[.]和1
3、第二行-第三行:
左边数字依次左一位
右边数字依次右一位
左边的[.]逐渐减少
右边的[.]逐渐增多
4、最后再打印最后一行
代码如下(示例):
import java.util.Scanner;
public class Nine8_等腰三角形 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//输入三角形的高度
int n = scanner.nextInt();
//计算出最终需要多少的数字
//两边的长度:2n-3;底边的长度:2n-1
int sum = 4 * (n - 1);
//创建一个空字符
String str = "";
for (int i = 0; str.length() < sum; i++) {
//转成字符串
str += String.valueOf(i);
}
//将字符串转换成字符数组
char[] chars = str.substring(0, sum).toCharArray();
//固定第一行的值为1
//因为无论三角形的高度有多高,第一行的值一直是1
for (int i = 0; i < n - 1; i++) {
//打印最左边的.
System.out.print(".");
}
//固定输出1
System.out.println(1);
//输出第二行至倒数第二行
for (int i = 1; i < n - 1; i++) { //从第二行开始
for (int j = 0; j < n - i - 1; j++) {
//打印最左边的.
System.out.print(".");
}
//输出值
System.out.print(chars[i]);
//输出中间的.
for (int j = 0; j < i * 2 - 1; j++) { //其实就是奇数的判断
System.out.print(".");
}
//输出值
System.out.println(chars[sum - i]);
}
//输出最后一行
for (int i = n - 1; i < sum - (n - 2); i++) {
System.out.print(chars[i]);
}
}
}
I.小朋友崇拜圈
问题描述:
班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。 在一个游戏中,需要小朋友坐一个圈, 每个小朋友都有自己最崇拜的小朋友在他的右手边。 求满足条件的圈最大多少人?
小朋友编号为1,2,3,…N
输入第一行,一个整数N(3<N<100000)
接下来一行N个整数,由空格分开。
要求输出一个整数,表示满足条件的最大圈的人数。
例如:
输入:
9
3 4 2 5 3 8 4 6 9
则程序应该输出:
4
解释:
如图p1.png所示,崇拜关系用箭头表示,红色表示不在圈中。
显然,最大圈是[2 4 5 3] 构成的圈
再例如:
输入:
30
22 28 16 6 27 21 30 1 29 10 9 14 24 11 7 2 8 5 26 4 12 3 25 18 20 19 23 17 13 15
程序应该输出:
16
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
注意:
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
做这道题时要认真点,仔细看题,审题。
代码如下(示例):
import java.util.ArrayList;
public class Nine9_小朋友崇拜圈 {
static int N = 9;
//储存最大的崇拜圈数量
static int max = 0;
static String maxStr = "";
public static void main(String[] args) {
String str = "3 4 2 5 3 8 4 6 9";
//崇拜圈临时变量
String quang = "";
String[] arr = str.split(" ");
for (int i = 0; i < arr.length; i++) {
quang = i + 1 + " ";
dg(i + 1, quang, arr);
}
System.out.println("最大圈: " + max +" [" + maxStr + "]");
}
/*
* 注:
* (1):equalsIgnoreCase方法的作用是将一个字符串与另一个字符串进行比较,在比较过程中忽略大小写(这就是与equal的区别)。
* 参数不为null,且这两个String相等(忽略大小写),则返回true;否则返回false。、
*
* (2):split函数能够指定分割符将字符串拆分成字符串数组
*/
public static void dg(int i, String quang, String[] arr) {
if(quang.split(" ")[0].equalsIgnoreCase(arr[i - 1])) { //找到圈
// System.out.println("找到圈:" + quang);
if(quang.split(" ").length > max) {
max = quang.split(" ").length;
maxStr = quang;
}
return;
}
quang += arr[i - 1] + " ";
// System.out.println(quang);
if(!quang.split(" ")[0].equalsIgnoreCase(arr[i - 1]) && quang.split(" ").length > N) { //死循环
return;
}
dg(Integer.parseInt(arr[i - 1]), quang, arr);
}
}
J.耐摔指数
问题描述:
x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。 各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。
如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n
为了减少测试次数,从每个厂家抽样3部手机参加测试。
如果已知了测试塔的高度,并且采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?
输入数据,一个整数n(3<n<10000),表示测试塔的高度。
输出一个整数,表示最多测试多少次。
例如:
输入:
3
程序应该输出:
2
解释:
手机a从2楼扔下去,坏了,就把b手机从1楼扔;否则a手机继续3层扔下
再例如:
输入:
7
程序应该输出:
3
解释:
a手机从4层扔,坏了,则下面有3层,b,c 两部手机2次足可以测出指数;
若是没坏,手机充足,上面5,6,7 三层2次也容易测出。
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
注意:请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。不要使用package语句。不要使用jdk1.7及以上版本的特性。主类的名字必须是:Main,否则按无效代码处理。
笨笨有话说:
我觉得3个手机太难了,要是2个手机还可以考虑一下。
歪歪有话说:
想什么呢,你!要是1部手机还用你编程啊?那样的话只好从下往上一层一层测。
这道题是挺难的,我也是借助了他人的代码,然后才一步步完成的。 代码如下(示例):
import java.util.Scanner;
public class Nine10_耐摔指数 {
//手机的数量
// static int nums = 3;
//暴力破解法
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//输入测试塔的高度
int n = scanner.nextInt();
scanner.close();
int[] temp = new int[1000];
int sum = 1;
for (int i = 0; sum < n; i++) {
sum = i + sum;
temp[i] = sum;
}
sum = 1;
int k = 0;
for (int i = 0; sum < n; i++) {
sum = temp[i] + sum;
k++;
}
System.out.println(k);
//递归
System.out.println(DroppingPhone(3, n));
}
//递归
public static long DroppingPhone(long phone, long floors) {
long times = 1;
while(DroppingMax(phone, times) < floors) {
times++;
}
return times;
}
public static long DroppingMax(long phone, long times) {
if(phone == 1) {
return times;
}
if(phone >= times) {
return (long) Math.pow(2, times) - 1;
}
return DroppingMax(phone, times - 1) + DroppingMax(phone - 1, times - 1) + 1;
}
}