第三届蓝桥杯javaC组真题

趣味算式

匪警请拨110,即使手机欠费也可拨通!

为了保障社会秩序,保护人民群众生命财产安全,警察叔叔需要与罪犯斗智斗勇,因而需要
经常性地进行体力训练和智力训练!

某批警察叔叔正在进行智力训练:

1 2 3 4 5 6 7 8 9 = 110;

请看上边的算式,为了使等式成立,需要在数字间填入加号或者减号(可以不填,但不能
填入其它符号)。之间没有填入符号的数字组合成一个数,例如:12+34+56+7-8+9 就是一种合格
的填法;123+4+5+67-89 是另一个可能的答案。

请你利用计算机的优势,帮助警察叔叔快速找到所有答案。

* 程序输出:

每个答案占一行。形如:

12+34+56+7-8+9
123+4+5+67-89
......

已知的两个答案可以输出,但不计分。

各个答案的前后顺序不重要。

注意:

请仔细调试!您的程序只有能运行出正确结果的时候才有机会得分!

下面附上最简单,但是效率非常差的一种解法,如果没有任何限定,此方法可行

效率耗费在调用js脚本函数上,所以我们后面给出,非js方法

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
 * @createDate:2019年3月11日 下午10:25:11
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:趣味算式.java @describe:
 */
public class 趣味算式JavaScript {

	static ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
	static String d;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str = "1";
		long startTime = System.currentTimeMillis();
		fun(str, 2);
		long endTime = System.currentTimeMillis();
		System.out.println("运行时间:" + (endTime - startTime) + "ms");
	}

	public static void fun(String str, int i) {
		if (i == 10) {
			try {
				String d = se.eval(str).toString();
				if (d.equals("110"))
					System.out.println(str);
			} catch (ScriptException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			fun(str + "-" + String.valueOf(i), i + 1);
			fun(str + "+" + String.valueOf(i), i + 1);
			fun(str + "" + String.valueOf(i), i + 1);
		}
	}
}

下面附上效率相对较高的解法

import java.util.Stack;

/**
 * @createDate:2019年3月12日 上午11:09:26
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:趣味算式.java @describe:
 */

public class 趣味算式 {
	static Stack<Character> sta = new Stack<Character>();
	static Stack<Integer> sums = new Stack<Integer>();

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str = "1";
		long startTime = System.currentTimeMillis();
		fun(str, 2);
		long endTime = System.currentTimeMillis();
		System.out.println("运行时间:" + (endTime - startTime) + "ms");
	}

	public static void fun(String str, int i) {
		if (i == 10) {
			if (GetStr(str) == 110) {
				System.out.println(str);
			}
		} else {
			fun(str + "-" + String.valueOf(i), i + 1);
			fun(str + "+" + String.valueOf(i), i + 1);
			fun(str + "" + String.valueOf(i), i + 1);
		}
	}

	public static int GetStr(String str) {
		int sum, t = 1, top, temp = 0, cnt = 0, b;
		char a;
		for (int i = str.length() - 1; i >= 0; i--) {
			// 补充算式算法
			if (str.charAt(i) == '+' || str.charAt(i) == '-') {
				sta.push(str.charAt(i));
				continue;
			} else {
				temp += t * (str.charAt(i) - '0');
				t *= 10;
			}

			if (i == 0 || str.charAt(i - 1) == '+' || str.charAt(i - 1) == '-') {
				sums.push(temp);
				t = 1;
				temp = 0;
			}
		}
		cnt = sta.size();
		for (int i = 0; i < cnt; i++) {
			a = sta.pop();
			if (a == '+') {
				top = sums.pop() + sums.pop();
				sums.push(top);
			} else if (a == '-') {
				top = sums.pop() - sums.pop();
				sums.push(top);
			}
		}
		int count = sums.pop();
		sta.clear();
		sums.clear();
		return count;
	}
}

 

 

总结:第二种方法使用了,波兰表达式的思想,堆栈计算


密码发生器

在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:如果为了好记用生日吧,
容易被破解,不安全;如果设置不好记的密码,又担心自己也会忘记;如果写在纸上,担心纸张被
别人发现或弄丢了...

这个程序的任务就是把一串拼音字母转换为6位数字(密码)。我们可以使用任何好记的拼音
串(比如名字,王喜明,就写:wangximing)作为输入,程序输出6位数字。

变换的过程如下:

第一步. 把字符串6个一组折叠起来,比如wangximing则变为:
wangxi
ming

第二步. 把所有垂直在同一个位置的字符的ascii码值相加,得出6个数字,如上面的例子,
则得出:
228 202 220 206 120 105

第三步. 再把每个数字“缩位”处理:就是把每个位的数字相加,得出的数字如果不是一位
数字,就再缩位,直到变成一位数字为止。例如: 228 => 2+2+8=12 => 1+2=3

上面的数字缩位后变为:344836, 这就是程序最终的输出结果!

要求程序从标准输入接收数据,在标准输出上输出结果。

输入格式为:第一行是一个整数n(<100),表示下边有多少输入行,接下来是n行字符串,
就是等待变换的字符串。
输出格式为:n行变换后的6位密码。

* 输入描述: 

例如,输入:
5
zhangfeng
wangximing
jiujingfazi
woaibeijingtiananmen
haohaoxuexi

* 程序输出:

772243
344836
297332
716652
875843

import java.util.Scanner;

/**
 * @createDate:2019年3月12日 下午7:11:42
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:密码发生器.java @describe:
 */
public class 密码发生器 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		String str[] = new String[n];
		for (int i = 0; i < n; i++) {
			str[i] = sc.next();
		}
		fun(str, n);

	}

	public static void fun(String str[], int n) {
		int arr[][] = new int[n][6];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < str[i].length(); j++) {
				arr[i][j % 6] += str[i].charAt(j);
			}
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < 6; j++) {
				arr[i][j] = funnum(arr[i][j]);
			}
		}

		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				System.out.print(arr[i][j]);
			}
			System.out.println();
		}
	}

	public static int funnum(int n) {
		if (n < 10)
			return n;
		int sum = 0;
		while (n > 0) {
			sum += n % 10;
			n /= 10;
		}
		return funnum(sum);
	}
}

 


手机尾号

30年的改革开放,给中国带来了翻天覆地的变化。2011全年中国手机产量约为11.72亿部。手机已经成为百姓的基本日用品!

给手机选个好听又好记的号码可能是许多人的心愿。但号源有限,只能辅以有偿选号的方法了。

这个程序的目的就是:根据给定的手机尾号(4位),按照一定的规则来打分。其规则如下:

1. 如果出现连号,不管升序还是降序,都加5分。例如:5678,4321都满足加分标准。

2. 前三个数字相同,或后三个数字相同,都加3分。例如:4888,6665,7777都满足加分的标准。注意:7777因为满足这条标准两次,所以这条规则给它加了6分。

3. 符合AABB或者ABAB模式的加1分。例如:2255,3939,7777都符合这个模式,所以都被加分。注意:7777因为满足这条标准两次,所以这条标准给它加了2分。

4. 含有:6,8,9中任何一个数字,每出现一次加1分。例如4326,6875,9918都符合加分标准。其中,6875被加2分;9918被加3分。

尾号最终得分就是每条标准的加分总和!

要求程序从标准输入接收数据,在标准输出上输出结果。

输入格式为:第一行是一个整数n(<100),表示下边有多少输入行,接下来是n行4位一组的数据,就是等待计算加分的手机尾号。
输出格式为:n行整数。

* 输入描述: 

例如,输入:
14
3045
0211
2345
6543
7777
8888
7878
7788
6688
2424
2244
9918
6789
8866

* 程序输出:

0
0
5
6
8
12
3
3
5
1
1
3
8
5

import java.util.Scanner;

/**
 * @createDate:2019年3月12日 下午7:38:27
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:手机尾号.java @describe:
 */
public class 手机尾号 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int arr[] = new int[n];
		for (int i = 0; i < n; i++) {
			arr[i] = sc.nextInt();
		}
		fun(arr, n);
	}

	public static void fun(int arr[], int n) {
		int ret[] = new int[n];
		int a, b, c, d, sum;
		for (int i = 0; i < n; i++) {
			sum = 0;
			a = arr[i] / 1000;
			b = arr[i] / 100 % 10;
			c = arr[i] / 10 % 10;
			d = arr[i] % 10;
			if (a == b - 1 && a == c - 2 && a == d - 3 || a == b + 1 && a == c + 2 && a == d + 3) {
				sum += 5;
			}
			if (b == c && b == d) {
				sum += 3;
			}
			if (a == b && a == c) {
				sum += 3;
			}
			if (a == b && c == d) {
				sum += 1;
			}
			if (a == c && b == d) {
				sum += 1;
			}
			if (a == 6 || a == 8 || a == 9) {
				sum += 1;
			}
			if (b == 6 || b == 8 || b == 9) {
				sum += 1;
			}
			if (c == 6 || c == 8 || c == 9) {
				sum += 1;
			}
			if (d == 6 || d == 8 || d == 9) {
				sum += 1;
			}
			ret[i] = sum;
		}
		for (int i = 0; i < ret.length; i++) {
			System.out.println(ret[i]);
		}
	}
}


括号问题

下面的代码用于判断一个串中的括号是否匹配
所谓匹配是指不同类型的括号必须左右呼应,可以相互包含,但不能交叉

例如:
..(..[..]..).. 是允许的
..(...[...)....].... 是禁止的 
对于 main 方法中的测试用例,应该输出:
false
true
false
false

import java.util.Stack;

/**
 * @createDate:2019年3月12日 下午7:58:15
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:括号问题.java @describe:
 */
public class 括号问题 {

	public static boolean isGoodBracket(String s) {
		Stack<Character> a = new Stack<Character>();

		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c == '(')
				a.push(')');
			if (c == '[')
				a.push(']');
			if (c == '{')
				a.push('}');

			if (c == ')' || c == ']' || c == '}') {
				if (a.empty())
					return false; // 填空
				if (a.pop() != c)
					return false;
			}
		}

		if (!a.empty())
			return false; // 填空

		return true;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(isGoodBracket("...(..[.)..].{.(..).}..."));
		System.out.println(isGoodBracket("...(..[...].(.).){.(..).}..."));
		System.out.println(isGoodBracket(".....[...].(.).){.(..).}..."));
		System.out.println(isGoodBracket("...(..[...].(.).){.(..)...."));
	}
}


扑克牌移动

下面代码模拟了一套扑克牌(初始排序A~K,共13张)的操作过程。

操作过程是:
手里拿着这套扑克牌,从前面拿一张放在后面,再从前面拿一张放桌子上,再从前面拿一张
放在后面,....
如此循环操作,直到剩下最后一张牌也放在桌子上。

下面代码的目的就是为了求出最后桌上的牌的顺序。

初始的排列如果是A,2,3...K,则最后桌上的顺序为:
[2, 4, 6, 8, 10, Q, A, 5, 9, K, 7, 3, J]

import java.util.Arrays;
import java.util.List;
import java.util.Vector;

/**
 * @createDate:2019年3月12日 下午8:20:15
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:扑克牌移动.java @describe:
 */
public class 扑克牌移动 {

	public static List moveCard(List src) {
		if (src == null)
			return null;

		List dst = new Vector();
		for (;;) {
			// 直到dst桌面排满
			if (dst.size() == 13)
				break; // 填空
			// remove(0)的返回值是A,然后Src.add()相当于把A移到了末尾(牌底)
			src.add(src.remove(0));
			 remove(0)的返回值是2,然后dst.add()相当于把2放到了桌面,从牌堆移除添加到dst
			dst.add(src.remove(0)); // 填空
		}

		return dst;
	}

	public static void main(String[] args) {
		List a = new Vector();
		a.addAll(Arrays.asList("A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"));
		System.out.println(moveCard(a));
	}
}


第一个数字

以下的静态方法实现了:把串s中第一个出现的数字的值返回。
如果找不到数字,返回-1

例如:
s = "abc24us43" 则返回2
s = "82445adb5" 则返回8
s = "ab" 则返回-1

public static int getFirstNum(String s)
{
if(s==null || s.length()==0) return -1;

char c = s.charAt(0);
if(c>='0' && c<='9') return _____________; //填空

return getFirstNum(______________); //填空
}

/**
 * @createDate:2019年3月12日 下午9:44:58
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:第一个数.java @describe:
 */
public class 第一个数 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(getFirstNum("abc24us43"));
		System.out.println(getFirstNum("82445adb5"));
		System.out.println(getFirstNum("ab"));
	}

	static int getFirstNum(String s) {
		if (s == null || s.length() == 0)
			return -1;

		char c = s.charAt(0);
		if (c >= '0' && c <= '9')
			return c - '0'; // 填空

		return getFirstNum(s.substring(1)); // 填空
	}

}


比酒量 

有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,所有在场的
人平分喝下,有几个人倒下了。再打开一瓶酒平分,又有倒下的,再次重复...... 直到
开了第4瓶酒,坐着的已经所剩无几,海盗船长也在其中。当第4瓶酒平分喝下后,大家
都倒下了。

等船长醒来,发现海盗船搁浅了。他在航海日志中写到:“......昨天,我正好喝
了一瓶.......奉劝大家,开船不喝酒,喝酒别开船......”

请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人。

如果有多个可能的答案,请列出所有答案,每个答案占一行。

* 程序输出:      格式是:人数,人数,...            例如,有一种可能是:20,5,4,2,0

/**
 * @createDate:2019年3月12日 下午9:48:26
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:比酒量.java @describe:
 */
public class 比酒量 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		for (int i = 20; i >= 1; i--) {
			for (int j = i - 1; j >= 1; j--) {
				for (int k = j - 1; k >= 1; k--) {
					for (int t = k - 1; t >= 1; t--) {
						if ((1.0 / i + 1.0 / j + 1.0 / k + 1.0 / t) == 1)
							System.out.printf("%d\t%d\t%d\t%d\t%d\n", i, j, k, t, 0);
					}
				}
			}
		}
	}
}

这题说是不能用1/x做但是注意下精度就没问题;反正我是这样的,不放心的你也可以用除法换算成乘法计算


 放麦粒

你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,
大臣说:请在第1个棋盘格放1粒麦子,在第2个棋盘格放2粒麦子,在第3个棋盘格放4粒
麦子,在第4个棋盘格放8粒麦子,......后一格的数字是前一格的两倍,直到放完所有
棋盘格(国际象棋共有64格)。

国王以为他只是想要一袋麦子而已,哈哈大笑。

当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用!

请你借助计算机准确地计算,到底需要多少粒麦子。

* 程序输出: 无

方法一:

import java.math.BigInteger;

/**
 * @createDate:2019年3月12日 下午10:36:56
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:放麦子.java @describe:
 */
public class 放麦子 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BigInteger sum = new BigInteger("1");
		for (int i = 1; i <= 64; i++) {
			sum = sum.multiply(BigInteger.valueOf(2));
		}
		sum = sum.subtract(BigInteger.ONE);
		System.out.println(sum);
	}
}

方法二:

import java.math.BigInteger;

/**
 * @createDate:2019年3月12日 下午10:36:56
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:放麦子.java @describe:
 */
public class 放麦子 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BigInteger sum = new BigInteger("0");
		BigInteger rt = new BigInteger("2");
		for (int i = 0; i < 64; i++) {
			sum = sum.add(rt.pow(i));
		}
		System.out.println(sum);
	}
}

更简单的理解方法

/**
 * @createDate:2019年3月12日 下午11:48:44
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:放麦粒2.java @describe:
 */
public class 放麦粒2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 第一格的麦粒
		BigInteger top = new BigInteger("1");
		// 总的麦粒
		BigInteger sum = new BigInteger("0");
		//因为我们有第一格的麦粒,所以我们从第2格一直到64的总和
		for (int i = 2; i <= 64; i++) {
			top = top.multiply(BigInteger.valueOf(2));
			sum = sum.add(top);
		}
		//加上第一个的麦粒数
		sum = sum.add(BigInteger.valueOf(1));
		//得出结果
		System.out.println(sum);
	}
}

总结:首先看到这题肯定没那么简单,结果你会发现你用long和int根本解不开这题,好了接下来说说解法,解法肯定是使用BigInteger超大整形类来解决问题。理解起来更简单的方法肯定是第三种,更符合常人逻辑、


猜年龄

今年的植树节(2012年3月12日),小明和他的叔叔还有小伙伴们一起去植树。休息
的时候,小明的同学问他叔叔多大年纪,他叔叔说:“我说个题目,看你们谁先猜出来!”

“把我出生的年月日连起来拼成一个8位数(月、日不足两位前补0)正好可以被今天
的年、月、日整除!”

他想了想,又补充到:“再给个提示,我是6月出生的。”

根据这些信息,请你帮小明算一下,他叔叔的出生年月日。

* 程序输出:   格式是年月日连成的8位数。    例如,如果是1948年6月12日,就写:19480612

* 程序头部的注释结束

/**
 * @createDate:2019年3月13日 上午12:12:47
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:猜年龄.java @describe:
 */
public class 猜年龄 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		long temp;
		for (int i = 1900; i <= 2012; i++) {
			for (int j = 1; j <= 30; j++) {
				temp = i * 10000 + 6 * 100 + j;
				if (temp % 2012 == 0 && temp % 12 == 0) {
					System.out.println(temp);
				}
			}
		}
	}
}

土地测量

造成高房价的原因有许多,比如土地出让价格。既然地价高,土地的面积必须仔细计算。遗憾的是,有些地块的形状不规则,比如是如图【1.jpg】中所示的五边形。

一般需要把它划分为多个三角形来计算。

已知三边求三角形的面积需要用海伦定理,参见【2.jpg】

各条边长数据如下:
AB = 52.1
BC = 57.2
CD = 43.5
DE = 51.9
EA = 33.4
EB = 68.2
EC = 71.9

/**
 * @createDate:2019年3月13日 上午12:39:20
 * @porjectName:lanqiao
 * @author Static
 * @version 1.0
 * @since JDK 1.8.0_21
 * @filename:土地测量.java @describe:
 */
public class 土地测量 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		double s1 = (52.1 + 33.4 + 68.2) / 2;
		double s2 = (68.2 + 71.9 + 57.2) / 2;
		double s3 = (51.9 + 71.9 + 43.5) / 2;

		double A1 = Math.sqrt(s1 * (s1 - 52.1) * (s1 - 33.4) * (s1 - 68.2));
		double A2 = Math.sqrt(s2 * (s2 - 68.2) * (s2 - 71.9) * (s2 - 57.2));
		double A3 = Math.sqrt(s3 * (s3 - 51.9) * (s3 - 71.9) * (s3 - 43.5));

		System.out.printf("%.2f", A1 + A2 + A3);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值