2014年第五届蓝桥杯省赛试题及详解(Java本科C组)

2022/3/26 22:22:36

本文主要是介绍2014年第五届蓝桥杯省赛试题及详解(Java本科C组),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1. 猜年龄

小明带两个妹妹参加元宵灯会。别人问她们多大了,她们调皮地说:“我们俩的年龄之积是年龄之和的6倍”。小明又补充说:“她们可不是双胞胎,年龄差肯定也不超过8岁啊。”

请你写出:小明的较小的妹妹的年龄。
注意: 只写一个人的年龄数字,请通过浏览器提交答案。

package 蓝桥2014C组;

public class T1 {

	public static void main(String[] args) {

		for (int i = 1; i <= 50; i++) {// 循环小妹妹的年龄
			for (int j = i + 1; j <= i + 8; j++) {// 循环大妹妹的年龄
				if ((i * j == (i + j) * 6)) {
					System.out.print(i);
				}
			}
		}
	}
//10
}
//注意外层循环是小妹妹的年龄 大妹妹的年龄的起始值i+1 终止值是i+8

2. 等额本金

小明从银行贷款3万元。约定分24个月,以等额本金方式还款。
这种还款方式就是把贷款额度等分到24个月。每个月除了要还固定的本金外,还要还贷款余额在一个月中产生的利息。
假设月利率是:0.005,即:千分之五。那么,
第一个月,小明要还本金 1250, 还要还利息:30000 * 0.005,总计 1400
第二个月,本金仍然要还 1250, 但利息为:(30000-1250) * 0.005 总计 1393.75

请问:小明在第15个月,应该还款多少(本金和利息的总和)?

请把答案金额四舍五入后,保留两位小数。注意:32.5,一定要写为:32.50

通过浏览器提交答案,这是一个含有小数点和两位小数的浮点数字。不要写多余内容(例如:多写了“元”或添加说明文字)
public static void main(String[] args) {

		System.out.println((30000 - 1250 * 14) * 0.005 + 1250);
	}

3. 猜字母

 把abcd...s共19个字母组成的序列重复拼接106次,得到长度为2014的串。
接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。
得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。
答案是一个小写字母,请通过浏览器提交答案。不要填写任何多余的内容。
package 蓝桥2014C组;

import java.util.ArrayList;
import java.util.List;

//删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。
//得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。
/*分析:
 * 1.先得到长为2014的串
 * 2.将串中的每个字符放到集合中
 * 3.不停地对处于奇数位的元素删除,只剩下一个字母为止
 * 4. 奇数位就对应于下标为偶数 i=i+2
 *  			for(int i=0;i<list.size();i=i+2) {
 				list.remove(i);
 但若采用上述删除:
 因为每删除一个元素,list.size()减小,它后面的元素的下标会有变化,就不能够确保它删除的一定是原来位于奇数位的
 解决:
 先去将所有处于奇数位的进行标记一下,第一轮删除时,将标记过的,进行删除
 进入第二轮,再重新将所有处于奇数位的进行标记一下,
 */
public class T3 {

	public static void main(String[] args) {
		String string = "";
		for (int i = 0; i <= 106; i++) {
			string += "abcdefghijklmnopqrs";
		}
		// 2.将串中的每个字符放到集合中
		List<Character> list = new ArrayList<>();
		for (int i = 0; i < string.length(); i++) {
			list.add(string.charAt(i));
		}
		// 3.利用循环去删除奇数位置的字母
		while (true) {
			// 死循环结束条件
			if (list.size() == 1) {
				System.out.println(list.get(0));
				break;
			}

//			for(int i=0;i<list.size();i=i+2) {
//				list.remove(i);
//			}
			// (1)做标记,将奇数位变成0
			for (int i = 0; i < list.size(); i = i + 2) {
				list.set(i,'0');
			}
			// (2)删除元素内容为‘0’的元素
			for (int i = 0; i < list.size(); i++) {
				if (list.get(i) == '0') {
					list.remove(i);
				}
			}
		}
	}
//q
}

5.写日志

写日志是程序的常见任务。现在要求在 t1.log, t2.log, t3.log 三个文件间轮流写入日志。也就是说第一次写入t1.log,第二次写入t2.log,... 第四次仍然写入t1.log,如此反复。

下面的代码模拟了这种轮流写入不同日志文件的逻辑。

请填写划线部分缺失的代码。通过浏览器提交答案。

public class A
{
    private static int n = 1;
    
    public static void write(String msg)
    {
        String filename = "t" + n + ".log";
        n = ____________;
        System.out.println("write to file: " + filename + " " + msg);
    }
}

代码实现:

private static int n = 1;   
    public static void write(String msg)
    {
        String filename = "t" + n + ".log";
//        n = n==3?1:n+1;
          n=n%3+1;
        System.out.println("write to file: " + filename + " " + msg);
    }
 
	public static void main(String[] args) {
		write("text");
		write("text");
		write("text");
		write("text");
		write("text");
		write("text");
	}
/*
write to file: t1.log text
write to file: t2.log text
write to file: t3.log text
write to file: t1.log text
write to file: t2.log text
write to file: t3.log text*/
}//注意:此题中的n是全局变量   n = n==3?1:n+1;  和  n=n%3+1;

6.李白打酒

话说大诗人李白,一生好饮。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:

无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。 

请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。

注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。

代码实现:

先来个简化版的:(与2013年的上台阶十分相似)

李白每走一步可能遇到店,也有可能遇到花,若李白一共走三步,求所有他遇到店和花的次序序列。

第一步:遇见花或者店

若花,第二步遇见花或者店

依次选下去,每一次两种选择,直到走3步

static char[] meet = new char[3];//记录每一次走法	
	public static void walk(int d,int h) {
		
		//递归出口
		if(d+h==3) {
			System.out.println(Arrays.toString(meet));
			return;
		}
		
		meet[d+h]='d';
		walk(d+1, h);//遇见店
		meet[d+h]='h';
		walk(d, h+1);//遇见花
	}
	
	public static void main(String[] args) {
	 
		int d =0;//遇到店的次数
		int h =0;//遇到花的次数
		walk(d, h);
	}
/*[d, d, d]
[d, d, h]
[d, h, d]
[d, h, h]
[h, d, d]
[h, d, h]
[h, h, d]
[h, h, h]*/
}

而此题除了考虑遇到店和花外,还有(1)酒的变化,不论遇到店和花,酒的量是都发生变化的(2)遇到店和花的次数有要求,一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。

package 蓝桥2014C组;

/*酒壶中有酒2斗,逢店加一倍,遇花喝一斗。一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。 
 请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b*/
/*fenxi:
 *  1. 只有遇到店的次数小于5次,才可能继续遇到店;遇到花的次数小于10次,才可能继续遇到花;
 *  2. 最后一次遇到的是花: 那就是遇到店5次,遇到花9次时,正好此时酒还剩1斗,这时只能遇到花,他正好把酒喝光了
 * */
public class T6 {

	static int count = 0;

	public static void walk(int wine, int d, int h) {

		// 递归出口
		if (d == 5 && h == 9&& wine==1) {
			count++;
			return;
		}
		if (d < 5) {
			walk(wine * 2, d + 1, h);// 遇见店,酒逢店加一倍,酒的量x2
		}
		if (h < 10) {
			walk(wine - 1, d, h + 1);// 遇花喝一斗。
		}
	}

	public static void main(String[] args) {

		int d = 0;// 遇到店的次数
		int h = 0;// 遇到花的次数
		int wine = 2;// 初始有有酒2斗
		walk(wine, d, h);
		System.out.println(count);
	}
//14
}

7.奇怪的分式:

上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:

1/4 乘以 8/5 
小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png)
老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!
对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢?
请写出所有不同算式的个数(包括题中举例的)。
显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。
但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!
注意:答案是个整数(考虑对称性,肯定是偶数)。请通过浏览器提交。不要书写多余的内容。
package 蓝桥2014C组;

/*对于分子、分母都是 1~9 中的一位数的情况;把分子拼接在一起,分母拼接在一起
 *但对于分子分母相同的情况, 不在计数之列;请写出所有不同算式的个数,肯定是偶数
 *fenxi:
 *1. 与之前全排列的多重循环不同的是:
 *    不是这四个数字都不相同哦!!只是每一个分式的分子和分母不相同即可
 *2. ax/ay x bx/by
 *  (ax*bx)/(ay*by) 与  (ax*10+bx)/(ay*10+by)是否相等
 *   若直接看两边是否== ,不行,因为若有除不进的,会有误差
 *3. 要求每一个分式的最大公约数:然后对于约分后的两个分式,比较分子与分子  分母与分母*/
public class T7 {
	static int count = 0;

	public static void main(String[] args) {
		// ax ay第一个分式的分子和分母 bx by第二个分式的分子和分母
		for (int ax = 1; ax <= 9; ax++) {

			for (int ay = 1; ay <= 9; ay++) {
				if (ax == ay)
					continue;
				for (int bx = 1; bx <= 9; bx++) {

					for (int by = 1; by <= 9; by++) {
						if (bx == by)
							continue;
						// 求两个分式的最大公约数
						int g1 = gcd(ax * bx, ay * by);
						int g2 = gcd(ax * 10 + bx, ay * 10 + by);
						// 对于约分后的两个分式,比较分子与分子 分母与分母
						if ((ax * bx) / g1 == (ax * 10 + bx) / g2 && (ay * by) / g1 == (ay * 10 + by) / g2) {
							count++;
						}

					}
				}
			}
		}
		System.out.println(count);
	}

	// 求一个分式的最大公约数
	public static int gcd(int x, int y) {
		if (y == 0)
			return x;
		else
			return gcd(y, x % y);
	}
//14
}

补充:

判断两个分式相等,除了第一种方法:将两个分式分别求最大公约数,进行各自的约分,然后比对它们的分子,分母都对应相等外;

第二种方法:第一个分式的分子乘以第二个分式的分母所的结果 与 第二个分式的分子乘以第一个分式的分母所的结果 比较,相等,就代表两个分式相等;

8.兰顿蚂蚁

 平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。
    蚂蚁的头部朝向为:上下左右其中一方。
蚂蚁的移动规则十分简单:
若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;
若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。

规则虽然简单,蚂蚁的行为却十分复杂。刚刚开始时留下的路线都会有接近对称,像是会重复,但不论起始状态如何,蚂蚁经过漫长的混乱活动后,会开辟出一条规则的“高速公路”。

蚂蚁的路线是很难事先预测的。
你的任务是根据初始状态,用计算机模拟兰顿蚂蚁在第n步行走后所处的位置。
【数据格式】

输入数据的第一行是 m n 两个整数(3 < m, n < 100),表示正方形格子的行数和列数。
接下来是 m 行数据。
每行数据为 n 个被空格分开的数字。0 表示白格,1 表示黑格。

接下来是一行数据:x y s k, 其中x y为整数,表示蚂蚁所在行号和列号(行号从上到下增长,列号从左到右增长,都是从0开始编号)。s 是一个大写字母,表示蚂蚁头的朝向,我们约定:上下左右分别用:UDLR表示。k 表示蚂蚁走的步数。

输出数据为两个空格分开的整数 p q, 分别表示蚂蚁在k步后,所处格子的行号和列号。

例如, 输入:
5 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
2 3 L 5
程序应该输出:
1 3

代码实现:

package 蓝桥2014C组;
import java.util.Scanner;
public class T8 {

	static int row;
	static int col;
	static int[][] arr;
	static char dir;

	public static void main(String[] args) {

		Scanner scanner = new Scanner(System.in);
		int m = scanner.nextInt();// 方格的行数
		int n = scanner.nextInt();// 方格的列数
		arr = new int[m][n];// 定义二维数组保存方格
		// 初始化方格
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				arr[i][j] = scanner.nextInt();// 输入时,0 表示白格,1 表示黑格
			}
		}
		// 蚂蚁所在行号和列号,都是从0开始编号
		row = scanner.nextInt();
		col = scanner.nextInt();
		// 蚂蚁头的朝向,我们约定:上下左右分别用:UDLR表示
		dir = scanner.next().charAt(0);// 注意scanner.next()得到是String
		// 表示蚂蚁走的步数
		int k = scanner.nextInt();

		// 按照蚂蚁走的步数,进行循环,每走一步,都按照"规则"进行,将一步规则写进方法中
		for (int i = 1; i <= k; i++) {
			// 先转向,再移动
			move();
		}

		System.out.println(row + " " + col);
	}

//	每走一步,都按照"规则"进行;
	// (1)必须知道蚂蚁的位置(行号,列号) arr[row][col],二维数组也需要 则这三个要改成全局静态变量
	// (2)获取当前格子的颜色:利用arr[row][col]是0或1,而知道
//	  若在黑格子里:若开始向上,则向右转;若开始向右,则向下转;
	public static void move() {
		if (arr[row][col] == 1) {// 若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;
			if (dir == 'U') {
				dir = 'R';
			} else if (dir == 'R') {
				dir = 'D';
			} else if (dir == 'D') {
				dir = 'L';
			} else {
				dir = 'U';
			}
			arr[row][col] = 0;
		} else if (arr[row][col] == 0) {// 若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。
			if (dir == 'U') {
				dir = 'L';
			} else if (dir == 'L') {
				dir = 'D';
			} else if (dir == 'D') {
				dir = 'R';
			} else {
				dir = 'U';
			}
			arr[row][col] = 1;
		}

		//// 先转向,再移动!!!!
		if (dir == 'U') {
			row--;
		} else if (dir == 'R') {
			col++;
		} else if (dir == 'D') {
			row++;
		} else {
			col--;
		}
	}
}

9.地宫取宝:

 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

代码:

package 蓝桥2014C组;

import java.util.Scanner;

/*分析:
 * 1.走到某个格子时:
 * 若此宝贝的价值大:有4种选择:向右走拿宝贝,向右走不拿宝贝,向下走拿宝贝,向下走不拿宝贝
 * 若此宝贝的价值小: 则不能那宝贝:向右走不拿宝贝,向下走不拿宝贝;
 * 2. 先判断宝贝的价值,大,则就写四个递归;小,则就写2个递归;*/
public class T9 {
	static int[][] digong;
	static int n;
	static int m;
	static int k;
	static long mount;// 方案的数量

	public static void main(String[] args) {

		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();// n 行
		m = scanner.nextInt();// m列
		k = scanner.nextInt();// 要取宝贝件数
		digong = new int[m][n];// 地宫矩阵
		// 初始化地宫格中宝贝的价值
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				digong[i][j] = scanner.nextInt();
			}
		}
		move(0, 0, -1, 0);// 注意此处的默认初始宝贝最大值,因为宝贝价值可以取到0; 开始时,若第一个宝贝价值就是0; 当max==0 ,则就不拿了;而实际上是可以拿的
		System.out.println(mount);
	}

	// 取宝贝的过程实现:
	// (1)小明的位置; (2)宝贝的最大值(判断当前宝贝的价值与手中所有宝贝进行比较,所以需要知道宝贝的最大值,是动态变化的)
	// (3) 小明手中宝贝的数量是动态变化的
	/**
	 * @param row   行走时的行
	 * @param col   行走时的列
	 * @param max   行走时的目前宝贝的最大价值
	 * @param count 行走时的宝贝的数量
	 */
	public static void move(int row, int col, int max, int count) {

		// 递归出口1:走出地宫外 或者 宝贝数量大于k
		if (row >= n || col >= m || count > k) {
			return;
		}
		// 递归出口2:
		// 不可以简单的认为只要k==count 因为小明若走到地宫的某处还未到出口时,就已经拿够了宝贝,就算接下来不拿,那可能也有多种方案走到出口
		// (1)当走到出口时,k==count
		// (2)当走到最后一个格子时,count=k-1,此时最后一个格子的价值又比较大,也符合条件

		if (row == n - 1 && col == m - 1) {// 走到最后一个格子
			if (count == k || (count == k - 1 && digong[row][col] > max)) {
				mount++;
				mount = mount % 1000000007;
			}
		}
		// 如果当前宝贝的价值大于目前宝贝的最大价值,有四种选择:
		if (digong[row][col] > max) {
			move(row, col + 1, digong[row][col], count + 1);// 拿了宝贝并向右走
			move(row, col + 1, max, count);// 右不拿
			move(row + 1, col, digong[row][col], count + 1);// 下拿
			move(row + 1, col, max, count);// 下不拿
		} else {// 如果当前宝贝的价值小于目前宝贝的最大价值,有2种选择:
			move(row, col + 1, max, count);// 右不拿
			move(row + 1, col, max, count);// 下不拿
		}
	}
}


这篇关于2014年第五届蓝桥杯省赛试题及详解(Java本科C组)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程