2014第五届蓝桥杯JavaA组省赛

第一题:猜年龄

题目描述
小明带两个妹妹参加元宵灯会。别人问她们多大了,她们调皮地说:“我们俩的年龄之积是年龄之和的6倍”。小明又补充说:“她们可不是双胞胎,年龄差肯定也不超过8岁啊。”
请你写出:小明的较小的妹妹的年龄。
注意: 只写一个人的年龄数字,请通过浏览器提交答案。不要书写任何多余的内容。


public class Demo01 {
	public static void main(String[] args) {
		for(int i = 1; i < 100-8; i++){
			for(int j = i+1; j <= i+8; j++){
				if(i*j == (i+j)*6){
					System.out.println(i + " " + j);
				}
			}
		}
	}
}
答案:10

第二题:李白打酒

题目描述
话说大诗人李白,一生好饮。幸好他从不开车。一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。
注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。



public class Demo02 {

	static int num = 0;

	public static void dfs(int i, int j, int sum) {
		if(sum < 0) return;
		if (i == 0 && j == 1 && sum == 1) {
			num++;
			return;
		}
		if (j > 0)
			dfs(i, j - 1, sum - 1);
		if (i > 0)
			dfs(i - 1, j, sum * 2);
	}

	public static void main(String[] args) {
		dfs(5, 10, 2);
		System.out.println(num);
	}
}
答案:14

第三题:神奇算式

题目描述
由4个不同的数字,组成的一个乘法算式,它们的乘积仍然由这4个数字组成。
比如:
210 x 6 = 1260
8 x 473 = 3784
27 x 81 = 2187 都符合要求。
如果满足乘法交换律的算式算作同一种情况,那么,包含上边已列出的3种情况,一共有多少种满足要求的算式。
请填写该数字,通过浏览器提交答案,不要填写多余内容(例如:列出所有算式)。



import java.util.Arrays;
import java.util.HashSet;

public class Demo03 {
	static boolean[] c = new boolean[10];
	static int[] a = new int[10];
	static int num;

	public static void dfs(int start) {
		if (start == 4) {
			int[] b = new int[4];
			b[0] = a[0];
			b[1] = a[1];
			b[2] = a[2];
			b[3] = a[3];
			Arrays.sort(b);
			if (a[0] != 0 && a[1] != 0) {
				int x = a[0] * (a[1] * 100 + a[2] * 10 + a[3]);
				if (x > 1000 && x < 10000) { // 保持为4位数
					int[] d = new int[4];
					d[0] = x % 10;
					d[1] = x / 10 % 10;
					d[2] = x / 100 % 10;
					d[3] = x / 1000 % 10;
					Arrays.sort(d);
					int i = 0;
					for (i = 0; i < 4; i++) {
						if (b[i] != d[i])
							break;
					}
					if (i == 4) {
						num++;
						System.out.println(a[0] + "*" + (a[1] * 100 + a[2] * 10 + a[3]) + "=" + x);
					}
				}

			}
			if (a[0] != 0 && a[2] != 0) {
				int y = (a[0] * 10 + a[1]) * (a[2] * 10 + a[3]);
				if (a[0] * 10 + a[1] >= 40)
				  return;
				if (y <= 1000 || y >= 10000)
					return;
				int[] f = new int[4];
				f[0] = y % 10;
				f[1] = y / 10 % 10;
				f[2] = y / 100 % 10;
				f[3] = y / 1000 % 10;

				Arrays.sort(f);

				int j = 0;
				for (j = 0; j < 4; j++) {
					if (b[j] != f[j])
						break;
				}
				if (j == 4) {
					num++;
					System.out.println((a[0] * 10 + a[1]) + "*" + (a[2] * 10 + a[3]) + "=" + y);
				}
			}

			return;
		}

		for (int i = 0; i < 10; i++) {
			if (!c[i]) {
				c[i] = true;
				a[start] = i;
				dfs(start + 1);
				c[i] = false;
			}
		}
	}

	public static void main(String[] args) {
		num = 0;
		dfs(0);
		System.out.println(num);
	}
}
答案:12

第四题:写日志

题目描述
写日志是程序的常见任务。现在要求在 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);
}
}
请填写划线部分缺失的代码。通过浏览器提交答案。
注意:不要填写题面已有的内容,也不要填写任何说明、解释文字。


 答案:n>=3?1:n+1;

第五题:锦标赛

题目描述
如果要在n个数据中挑选出第一大和第二大的数据(要求输出数据所在位置和值),使用什么方法比较的次数最少?我们可以从体育锦标赛中受到启发。
如图【1.png】所示,8个选手的锦标赛,先两两捉对比拼,淘汰一半。优胜者再两两比拼…直到决出第一名。 第一名输出后,只要对黄色标示的位置重新比赛即可。下面的代码实现了这个算法(假设数据中没有相同值)。代码中需要用一个数组来表示图中的树(注意,这是个满二叉树, 不足需要补齐)。它不是存储数据本身,而是存储了数据的下标。 第一个数据输出后,它所在的位置被标识为-1

class A{
//a 表示待处理的数据,长度如果不是2的次幂,则不足位置补为-1
static void pick(int[] a)
{
int n = 1;
while(n<a.length) n *= 2;

    int[] b = new int[2*n-1];
    for(int i=0; i<n; i++){ 
        if(i<a.length) 
            b[n-1+i] = i;
        else
            b[n-1+i] = -1;
    }
    
    //从最后一个向前处理
    for(int i=b.length-1; i>0; i-=2){
        if(b[i]<0){
            if(b[i-1]>=0)
                b[(i-1)/2] = b[i-1]; 
            else
                b[(i-1)/2] = -1;
        }
        else{
            if(a[b[i]]>a[b[i-1]])
                b[(i-1)/2] = b[i];
            else
                b[(i-1)/2] = b[i-1];
        }
    }
    
    //输出树根
    System.out.println(b[0] + ": " + a[b[0]]);
    
    //值等于根元素的位置需要重新pk
    pk(a,b,0,b[0]);
    
    //再次输出树根
    System.out.println(b[0] + ": " + a[b[0]]);
}

// a 表示待处理数据,b 二叉树,k 当前要重新比拼的位置,v 已经决胜出的值    
   static void pk(int[] a, int[] b, int k, int v)
{
    
    int k1 = k*2+1;
    int k2 = k1 + 1;
    
    if(k1>=b.length || k2>=b.length){
        b[k] = -1;
        return;
    }
    
    if(b[k1]==v) 
        pk(a,b,k1,v);
    else
        pk(a,b,k2,v);
    
    
    //重新比较
    if(b[k1]<0){
        if(b[k2]>=0)
            b[k] = b[k2]; 
        else
            b[k] = -1;
        return;
    }
    
    if(b[k2]<0){
        if(b[k1]>=0)
            b[k] = b[k1]; 
        else
            b[k] = -1;
        return;
    }
    
    if(__________________________)  //填空
        b[k] = b[k1];
    else
        b[k] = b[k2];
}
}

请仔细分析流程,填写缺失的代码。

通过浏览器提交答案,只填写缺失的代码,不要填写已有代码或其它说明语句等。
在这里插入图片描述


class A {
	// a 表示待处理的数据,长度如果不是2的次幂,则不足位置补为-1
	static void pick(int[] a) {
		int n = 1;
		while (n < a.length)
			n *= 2;

		int[] b = new int[2 * n - 1];
		for (int i = 0; i < n; i++) {
			if (i < a.length)
				b[n - 1 + i] = i;
			else
				b[n - 1 + i] = -1;
		}

		// 从最后一个向前处理
		for (int i = b.length - 1; i > 0; i -= 2) {
			if (b[i] < 0) {
				if (b[i - 1] >= 0)
					b[(i - 1) / 2] = b[i - 1];
				else
					b[(i - 1) / 2] = -1;
			} else {
				if (a[b[i]] > a[b[i - 1]])
					b[(i - 1) / 2] = b[i];
				else
					b[(i - 1) / 2] = b[i - 1];
			}
		}

		// 输出树根
		System.out.println(b[0] + ": " + a[b[0]]);

		// 值等于根元素的位置需要重新pk
		pk(a, b, 0, b[0]);

		// 再次输出树根
		System.out.println(b[0] + ": " + a[b[0]]);
	}

	// a 表示待处理数据,b 二叉树,k 当前要重新比拼的位置,v 已经决胜出的值
	static void pk(int[] a, int[] b, int k, int v) {

		int k1 = k * 2 + 1;
		int k2 = k1 + 1;

		if (k1 >= b.length || k2 >= b.length) {
			b[k] = -1;
			return;
		}

		if (b[k1] == v)
			pk(a, b, k1, v);
		else
			pk(a, b, k2, v);

		// 重新比较
		if (b[k1] < 0) {
			if (b[k2] >= 0)
				b[k] = b[k2];
			else
				b[k] = -1;
			return;
		}

		if (b[k2] < 0) {
			if (b[k1] >= 0)
				b[k] = b[k1];
			else
				b[k] = -1;
			return;
		}

		if (a[b[k1]] > a[b[k2]]) // 填空
			b[k] = b[k1];
		else
			b[k] = b[k2];
	}
}

public class Demo15 {
	public static void main(String[] args) {
		int a[]={1,8,22,15,3,6,12,13};
		new A().pick(a);
	}
}
答案:a[b[k1]] > a[b[k2]

第六题:六角填数

题目描述
如图【1.png】所示六角形中,填入1~12的数字。使得每条直线上的数字之和都相同。 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?
请通过浏览器提交答案,不要填写多余的内容。
在这里插入图片描述


import java.util.Arrays;
import java.util.HashSet;

public class Demo16 {
	static boolean[] c = new boolean[13];
	static int[] a = new int[13];
	static int num;

	public static void dfs(int start) {
		if (start == 12) {
			if (a[0] != 1 || a[1] != 8 || a[11] != 3)
				return;
			HashSet<Integer> set = new HashSet<>();
			set.add(a[0] + a[2] + a[5] + a[7]);
			set.add(a[1] + a[2] + a[3] + a[4]);
			set.add(a[7] + a[8] + a[9] + a[10]);
			set.add(a[0] + a[3] + a[6] + a[10]);
			set.add(a[1] + a[5] + a[8] + a[11]);
			set.add(a[4] + a[6] + a[9] + a[11]);
			if(set.size() == 1){
				System.out.println(a[5]);
			}
			return;
		}

		for (int i = 1; i < 13; i++) {
			if (!c[i]) {
				c[i] = true;
				a[start] = i;
				dfs(start + 1);
				c[i] = false;
			}
		}
	}

	public static void main(String[] args) {
		num = 0;
		dfs(0);
		System.out.println(num);
	}
}
答案:10

第七题:绳圈

题目描述
今有 100 根绳子,当然会有 200 个绳头。
如果任意取绳头两两配对,把所有绳头都打结连接起来。最后会形成若干个绳(不考虑是否套在一起)。 我们的问题是:请计算最后将形成多少个绳圈的概率最大?
注意:结果是一个整数,请通过浏览器提交该数字。不要填写多余的内容。


public class Demo17 {
	public static void main(String[] args) {

		final int N = 100;
		double dp[][] = new double[N+1][N+1];

		dp[1][1] = 1;
		for (int i = 2; i <= N; i++) {
			dp[i][1] = dp[i - 1][1] * (2 * i - 2) / (2 * i - 1);
			dp[i][i] = dp[i - 1][i - 1] / (2 * i - 1);
		}

		for (int i = 3; i <= N; i++) {
			for (int j = 2; j < i; j++) {
				dp[i][j] = dp[i - 1][j - 1] / (2 * i - 1) + dp[i - 1][j] * (2 * i - 2) / (2 * i - 1);
			}
		}

		int index = 0;
		double maxR = 0;
		for (int i = 1; i <= N; i++) {
			if (dp[N][i] > maxR) {
				index = i;
				maxR = dp[N][i];
			}
		}
		System.out.println(index);
	}

}
答案:3

第八题:兰顿蚂蚁

题目描述
兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。蚂蚁的头部朝向为:上下左右其中一方。 蚂蚁的移动规则十分简单: 若蚂蚁在黑格,右转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

再例如, 输入:
3 3
0 0 0
1 1 1
1 1 1
1 1 U 6
程序应该输出:
0 0

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
在这里插入图片描述


import java.util.Scanner;

public class Demo04 {
	static int n, m, x, y, k;
	static String direction;
	static char dir;
	static int[][] a = new int[100][100];

	private static void dfs(int x2, int y2, char dir2, int k2) {
		if(k2 == 0) {
			System.out.println(x2 + " " + y2);
			return;
		}
		if (a[x2][y2] == 1) {
			if (dir2 == 'U') {
				a[x2][y2] = 0;
				dfs(x2,y2+1,'R',k2-1);
			}
			if (dir2 == 'D') {
				a[x2][y2] = 0;
				dfs(x2,y2-1,'L',k2-1);
			}
			if (dir2 == 'L') {
				a[x2][y2] = 0;
				dfs(x2-1,y2,'U',k2-1);
			}
			if (dir2 == 'R') {
				a[x2][y2] = 0;
				dfs(x2+1,y2,'D',k2-1);
			}
		}
		else{
			if (dir2 == 'U') {
				a[x2][y2] = 1;
				dfs(x2,y2-1,'L',k2-1);
			}
			if (dir2 == 'D') {
				a[x2][y2] = 1;
				dfs(x2,y2+1,'R',k2-1);
			}
			if (dir2 == 'L') {
				a[x2][y2] = 1;
				dfs(x2+1,y2,'D',k2-1);
			}
			if (dir2 == 'R') {
				a[x2][y2] = 1;
				dfs(x2-1,y2,'U',k2-1);
			}
		}
	}

	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		n = cin.nextInt();
		m = cin.nextInt();
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				a[i][j] = cin.nextInt();
			}
		}
		x = cin.nextInt();
		y = cin.nextInt();
		direction = cin.next();
 		k = cin.nextInt();
		dir = direction.charAt(0);
		dfs(x, y, dir, k);
	}
}

第九题:斐波那契

题目描述
斐波那契数列大家都非常熟悉。它的定义是:
f(x) = 1 … (x=1,2)
f(x) = f(x-1) + f(x-2) … (x>2)
对于给定的整数 n 和 m,我们希望求出: f(1) + f(2) + … + f(n) 的值。但这个值可能非常大,所以我们把它对 f(m) 取模。公式参见【图1.png】但这个数字依然很大,所以需要再对 p 求模。

【数据格式】
输入为一行用空格分开的整数 n m p (0 < n, m, p < 10^18)
输出为1个整数

例如,如果输入:
2 3 5
程序应该输出:0
0

再例如,输入:
15 11 29
程序应该输出:
25

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

在这里插入图片描述


第十题:波动数列

题目描述
观察这个数列:
1 3 0 2 -1 1 -2 …

这个数列中后一项总是比前一项增加2或者减少3。
栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢?

【数据格式】
输入的第一行包含四个整数 n s a b,含义如前面说述。
输出一行,包含一个整数,表示满足条件的方案数。由于这个数很大,请输出方案数除以100000007的余数。

例如,输入:
4 10 2 3
程序应该输出:
2

【样例说明】
这两个数列分别是2 4 1 3和7 4 1 -2。

【数据规模与约定】
对于10%的数据,1<=n<=5,0<=s<=5,1<=a,b<=5;
对于30%的数据,1<=n<=30,0<=s<=30,1<=a,b<=30;
对于50%的数据,1<=n<=50,0<=s<=50,1<=a,b<=50;
对于70%的数据,1<=n<=100,0<=s<=500,1<=a, b<=50;
对于100%的数据,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。


0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值