第十一届蓝桥杯Java省赛第二场B组部分题解

本文章会讲解部分题解(因为有的题不会!!,太菜了),如果大家发现解答有问题,可以留言,大家一起讨论。

试题A: 

答案:624

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a = 1;
		int count = 0;
		while (true) {
			String b = a + "";
			for (int i = 0; i < b.length(); i++) {
				if (b.charAt(i) == '2') {
					count++;
				}
			}
			a++;
			if (a == 2021) {
				System.out.println(count);
				return;
			}
		}
	}

第一题相对简单,直接从1到2020遍历,判断有多少个2即可。

试题B:

答案:16520

	public static void main(String[] args) {
		int l = 1000;
		String arr[] = new String[300];
		int arr2[][] = new int[300][300];
		Scanner s = new Scanner(System.in);
		int count = 0; // 计算多少个2020
		String target = "2020";
		String b = "";
		for (int i = 0; i < 300; i++) {
			arr[i] = s.next();
		}
//		将输入的字符串转换成数组
		for (int i = 0; i < arr.length; i++) {
			for (int z = 0; z < arr[i].length(); z++) {
				arr2[i][z] = (arr[i].charAt(z) - '0');
			}
		}
//		判断上下左右斜对角的方法
		for (int i = 0; i < arr2.length; i++) {
			for (int j = 0; j < arr2[i].length; j++) {
				if (arr2[i][j] == 2) {
					b = "";
//					左 -》右
//					if (j + 4 <= arr2[i].length) {
//						for (int k = j; k < j + 4; k++) {
//							b = b + arr2[i][k];
//						}
//						if (b.equals(target)) {
//							count++;
//							b = "";
//						}
//					}
//					上 -》下
//					if (i + 4 <= arr2[i].length) {
//						for (int k = i; k < i + 4; k++) {
//							b = b + arr2[k][j];
//						}
//						if (b.equals(target)) {
//							count++;
//							b = "";
//						}
//					}
					左上 - > 右下
					if (i + 4 <= arr2[i].length && j + 4 <= arr2[i].length) {
						int n = i;
						int m = j;
						for (int k = 0; k < 4; k++) {
							b = b + arr2[n][m];
							n++;
							m++;
						}
						if (b.equals(target)) {
							count++;
							b = "";
						}
					}
				}
			}
		}
		System.out.println(count);
	}

解题思路:首先,题目中说明了三种寻找的方式,必定需要拿出每一位字符进行判断和拼接,来检测是否满足条件。但是如果你要拿出每一位字符,最好的办法就是将输入的值,将每一个字符存入一个二维数组。这样就能方便后续的计算。首先, 你需要知道输入的值需要存入一个一维的字符串数组,每一行就看作一个字符串存入数组中,然后将这个一维的字符串数组转成二维的数组。将数组中的每一个字符存入数组。接着开始遍历二维数组,如果取出的当前字符为2,则就需要判断这个字符从左到右,从上到下,从左上到右下是不是满足要求,如果满足要求则count++,这里需要注意的就是要防止数组的越界。

我这里遇到一个问题,我用三个if来分别判断左->右 ,上->下,左上-> 右下,但是如果我同时执行三个if的话,结果不准确。如果每次只执行一个if语句,结果就准确,现在也没有找到原因。于是我执行了三次程序,分别计算出了左->右共5505个满足条件的,从上->下有5509个满足条件的,从左上->右下,共有5506个满足条件的。所以结果为5505+5506+5509 = 16520.如果大家找出为什么三个if同时执行结果不同的原因,可以留言交流!!! 

 

试题C:

答案: 761

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a = 1;
		for (int i = 0; i < 20; i++) {
			a = a + (i * 4);
			System.out.println(a);
		}
	}

解题思路:先手写几行就可以发现,第一行第一列的值为1,第二行第二列的值为5.第三行第三列的值为13,第四行第四列的值为25,仔细观察就可以发现第i行第i列的值为  a = a + (i*4)。

试题F:

答案: jonmlkihgfedcba

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String a = "jonmlkihgfedcba";
		StringBuffer sb = new StringBuffer(a);
		int i = 0;
		int count = 0;
		while (true) {
			if (i < a.length() - 1 && a.charAt(i) > a.charAt((i + 1))) {
				sb.replace(i, i + 1, a.charAt((i + 1)) + "");
				sb.replace(i + 1, i + 2, a.charAt((i)) + "");
				a = sb.toString();
				count++;

				continue;
			} else if (i < a.length() - 1 && i - 1 >= 0 && a.charAt(i) < a.charAt((i - 1))) {
				sb.replace(i - 1, i, a.charAt((i)) + "");
				sb.replace(i, i + 1, a.charAt((i - 1)) + "");
				a = sb.toString();
				count++;
				i--;
				continue;
			} else {
				i++;
				if (i == a.length() - 1) {
					System.out.println(count);
					System.out.println(a);
					break;
				}
			}
		}
		if (count == 100) {
			System.out.println(a);
			return;
		}
	}

解题思路:首先根据题目所给交换规则,写一个完整的程序,并且当交换完成之后,要输出交换次数(count),和最后的结果(a),输出这两个值来判断程序是否正确。例如:当a为lan时,输出1 和aln;当a为waqs时,输出3和aqsw。此时,就可以开始找长度最短,并且字典序最小的呢个字符串了。题目中最后一句描述有错,应该是字符串中不能有重复的字符。当a=zyxw时,输出的count值为6,此时你应该知道,当字符串的长度为4时,最大的交换次数为6。因为最左边的要移动到最右边,最右边的要移动到最左边。所以首先根据这个找出满足条件的字符串长度,当a=zyxwvutsrqponm时,最大的交换次数为91,当a = zyxwvutsrqponml时,最大的交换次数为105,所以交换次数为100的字符串的长度必定为15。而且还需要字典序最小,所以从a开始倒叙排列15个字符, a=onmlkjihgfedcba时,交换次数为105次,为了满足交换次数恰好100次,将j向前移动5位即可。所以答案为jonmlkihgfedcba。

 

试题F:

public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int count = s.nextInt();
		DecimalFormat df = new DecimalFormat(".00");
		int arr[] = new int[count];
		double num = 0;
		for (int i = 0; i < arr.length; i++) {
			arr[i] = s.nextInt();
			num += arr[i];
		}
		Arrays.sort(arr);
		System.out.println(arr[count - 1]);
		System.out.println(arr[0]);
		System.out.println(df.format(num / count));
	}

这道题没有什么技术含量,考的主要是基础,感兴趣的朋友可以将多种保留小数的方式测试一下。

试题G:

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s = new Scanner(System.in);
		int max = -1;
		char maxs = 'a';
		String a = s.next();
		HashMap<String, Integer> map = new HashMap<>();
		for (int i = 0; i < a.length() - 1; i++) {
			if (map.get(a.charAt(i) + "") != null) {
				int num = (int) map.get(a.charAt(i) + "");
				map.remove(a.charAt(i) + "");
				num++;
				map.put(a.charAt(i) + "", num);
			} else {
				map.put(a.charAt(i) + "", 1);
			}
		}
		Object[] arr = map.entrySet().toArray();
		for (int i = 0; i < arr.length; i++) {
			String arr2[] = (arr[i] + "").split("=");
			if ((Integer.parseInt(arr2[1])) >= max) {
				if ((Integer.parseInt(arr2[1])) == max) {
					if (arr2[0].charAt(0) > maxs) {
						maxs = arr2[0].charAt(0);
						continue;
					}
				}
				max = (Integer.parseInt(arr2[1]));
				maxs = arr2[0].charAt(0);
			}
		}
		System.out.println(maxs);
		System.out.println(max);
	}

解题思路:使用map集合对每个字符出现的次数进行保存,最后将结果转成数组进行遍历,找出出现最多的字符。

试题I:

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s = new Scanner(System.in);
		String a = s.next();
		HashMap<String, Integer> map = new HashMap<>();
		int count = 0;
		for (int i = 0; i < a.length(); i++) {
			for (int j = i + 1; j <= a.length(); j++) {
				String b = a.substring(i, j);
				map.clear();
				for (int k = 0; k < b.length(); k++) {
					if (map.get(b.charAt(k) + "") == null) {
						map.put(b.charAt(k) + "", 1);
					}
				}
				count += map.size();
			}
		}
		System.out.println(count);
	}

解题思路:首先利用双指针对字符串进行截取,截取之后逐个取出字符串的每个字符串存入map集合,如果map集合中没有此字符串则放入map集合中,最后获取size。其实这里可以利用set本身去重的特点,来替换map集合。

 

以上就是我写出的答案,部分题还没有写出完整的答案,后续会不断的修改本文章,不断的将解题补充完整。如果以上答案有什么不对或者可以优化的地方,欢迎大家指正!

  • 10
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值