2019 第十届蓝桥杯Java省赛B组我的题解

2019 第十届蓝桥杯Java省赛B组我的题解

前言

  如下的第十届蓝桥杯Java B组省赛的题目题解只是我我的的题解,提供一些解题思路,仅做参考,若有错误,望你们指出,不胜感激,我会及时更改。java

  原本想把比赛题目上传到CSDN上免费下载,上传以后发现默认是5积分(根据下载热度和评星积分会本身调整),后来了解到如今的CSDN向知识付费靠拢,激励用户上传资源,取消了用户自行订价的功能和下架资源的功能(须要找客服下架,客服根本不理啊)。node

  2019 第十届蓝桥杯Java省赛B组题目——CSDN(须要5或者更多积分(系统本身调的),但愿你们尽可能下载下面连接的,谁的积分来的都不容易)web

  2019 第十届蓝桥杯Java省赛B组题目下载——提取码: yukk数组

试题A:组队——答案:490

import java.util.Scanner;
/** * * @ClassName: Team组队 * @Description: 题目不难理解,让有的人迷糊的可能就是一个队员只能选中一次。此题考试手动筛选一下就行,想写程序验证的也能够。 * @author: colou * @date: 2019年3月30日 上午8:58:21 */
public class Team组队 {

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			int[][] team = new int[20][5];
			for (int i = 0; i < 20; i++) {
				for (int j = 0; j < 5; j++) {
					team[i][j] = input.nextInt();
				}
			}
			int maxSum = 0;
			for (int i = 0; i < 20; i++)
				for (int j = 0; j < 20; j++)
					for (int k = 0; k < 20; k++)
						for (int h = 0; h < 20; h++)
							for (int g = 0; g < 20; g++)
								if ((i != j && i != k && i != h && i != g) && (j != k && j != h && j != g)
										&& (k != h && k != g) && h != g) {
									int max = team[i][0] + team[j][1] + team[k][2] + team[h][3] + team[g][4];
									if (max > maxSum)
										maxSum = max;
								}
			System.out.println(maxSum);
			// 测试用例
			/* * 97 90 0 0 0 92 85 96 0 0 0 0 0 0 93 0 0 0 80 86 89 83 97 0 0 82 86 0 0 0 0 0 * 0 87 90 0 97 96 0 0 0 0 89 0 0 95 99 0 0 0 0 0 96 97 0 0 0 0 93 98 94 91 0 0 * 0 0 83 87 0 0 0 0 98 97 98 0 0 0 93 86 98 83 99 98 81 93 87 92 96 98 0 0 0 89 * 92 0 99 96 95 81 */
		} catch (Exception e) {
			input.close();
		}
	}
}

试题B:不一样子串——答案:100

import java.util.HashSet;
import java.util.Set;

/** * * @ClassName: DifferentSubstring不一样子串 * @Description: 审题发现要求是不一样的非空子串,则想到Set集合去重,String.substring()方法求子串(一切 为快速解题为前提),而后咱们发现它的子串规律为一开始子串长度为1,而后在为2,……,最后为原字符串,这就好 比切豆腐,一开始要求切成每刀间隔为1豆腐块,每次移动距离为1,后来要求切成每刀间隔为2豆腐块,每次移动距离 为1,……,直至为整个大豆腐的大小。 * @author: colou */
public class DifferentSubstring不一样子串 {
	public static void main(String[] args) {
		String target = "0100110001010001";
		Set<String> sub = new HashSet<String>();
		for (int step = 0; step <= target.length() - 1; step++) {
			for (int beginIndex = 0, endIndex = 1 + step; endIndex <= target.length(); beginIndex++, endIndex++) {
				sub.add(target.substring(beginIndex, endIndex));
			}
		}
		System.out.println(sub.size());
	}
}

试题C:数列求值——答案:4659

/** * * @ClassName: SequenceEvaluation数列求值 * @Description: 此题相似于斐波那契数列,可是所求20190324项的最后四位数字,要是单纯按照斐波那契数列的 * 思想求下去,别说long类型,BigInteger类型都存不了这么大的数,而后咱们发现,所求 * 20190324项的最后四位数字(也就是变相的告诉咱们运算过程只和每一个数的后四位有关系),那 么咱们只须要保留每次运算结果的后四位就OK了,这样绝对不会溢出。 * @author: colou */
public class SequenceEvaluation数列求值 {

	public static void main(String[] args) {
		int a = 1, b = 1, c = 1;
		// 要是求第四项,则i < 4, 同理推得求20190324,则i < 20190324。
		for (int i = 3; i < 20190324; i++) {
			int temp = (a + b + c) % 10000;
			a = b;
			b = c;
			c = temp;
		}
		System.out.println(c);
	}
}

试题D:数的分解——答案:40785

/** * * @ClassName: DecompositionOfNumbers数的分解 * @Description: 首先咱们分析组成2019的三个数有哪几类?1.ABC类排列方式为六种(ABC,ACB,BAC,BCA, * CAB,CBA),2.AAB类排列方式有三种(AAB,ABA,BAA),3.AAA类排列方式一种。而题目要 * 求把 2019 分解成 3 个各不相同的正整数之和也就是说只保留ABC类的组合方式,j = i + 1,减小一半排列方式。 * @author: colou */
public class DecompositionOfNumbers数的分解 {

	public static void main(String[] args) {
		int n = 2019;
		int num = 0;
		for (int i = 1; i < n; i++) {
			if ((i + "").indexOf("2") != -1 || (i + "").indexOf("4") != -1)
				continue;
			for (int j = i + 1; j < n; j++) {
				if ((j + "").indexOf("2") != -1 || (j + "").indexOf("4") != -1)
					continue;
				int k = n - i - j;
				if (i == k || j == k || i == j)
					continue;
				if (k > 0 && (k + "").indexOf("2") == -1 && (k + "").indexOf("4") == -1)
					num++;
			}
		}
		System.out.println(num / 3);
	}
}

试题E:迷宫

答案:DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;

/** * @ClassName: LabyrinthProblem迷宫问题 * @Description: 广度优先搜索:https://blog.csdn.net/raphealguo/article/details/7523411 * https://blog.csdn.net/u011815404/article/details/79582206 * @author: colou */
public class Labyrinth迷宫 {
	/* * 深度优先能够这样想,一我的迷路,遇到不少分叉路口,他只有一我的,而且想走出去,因此只能一个个尝试, * 一条道路走到黑,发现到头了,而后再拐回去走刚才这条路的其余分叉路口,最后发现这条路的全部分叉路口走完了 * ,选择另一条路继续以上操做,直到全部的路都走过了。 * 广度优先并非这样,一我的迷路,可是他有技能(分身术)它遇到分叉路口,不是选一个走,而是分身多我的都试试, * 好比有A、B、C三个分叉路口,它A路走一步,紧接着B路也走一步,而后C路也赶忙走一步,步伐整齐统一,直到全部的路走过了。 */ public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			String s = "01010101001011001001010110010110100100001000101010"
					+ "00001000100000101010010000100000001001100110100101"
					+ "01111011010010001000001101001011100011000000010000"
					+ "01000000001010100011010000101000001010101011001011"
					+ "00011111000000101000010010100010100000101100000000"
					+ "11001000110101000010101100011010011010101011110111"
					+ "00011011010101001001001010000001000101001110000000"
					+ "10100000101000100110101010111110011000010000111010"
					+ "00111000001010100001100010000001000101001100001001"
					+ "11000110100001110010001001010101010101010001101000"
					+ "00010000100100000101001010101110100010101010000101"
					+ "11100100101001001000010000010101010100100100010100"
					+ "00000010000000101011001111010001100000101010100011"
					+ "10101010011100001000011000010110011110110100001000"
					+ "10101010100001101010100101000010100000111011101001"
					+ "10000000101100010000101100101101001011100000000100"
					+ "10101001000000010100100001000100000100011110101001"
					+ "00101001010101101001010100011010101101110000110101"
					+ "11001010000100001100000010100101000001000111000010"
					+ "00001000110000110101101000000100101001001000011101"
					+ "10100101000101000000001110110010110101101010100001"
					+ "00101000010000110101010000100010001001000100010101"
					+ "10100001000110010001000010101001010101011111010010"
					+ "00000100101000000110010100101001000001000000000010"
					+ "11010000001001110111001001000011101001011011101000"
					+ "00000110100010001000100000001000011101000000110011"
					+ "10101000101000100010001111100010101001010000001000"
					+ "10000010100101001010110000000100101010001011101000"
					+ "00111100001000010000000110111000000001000000001011"
					+ "10000001100111010111010001000110111010101101111000";
			int[][] labyrinth = new int[30][50];
			for (int i = 0; i < 30; i++) {
				for (int j = 0; j < 50; j++) {
					labyrinth[i][j] = s.charAt(50 * i + j) - '0';
				}
			}
			System.out.println(BFS(labyrinth, 30, 50));
		} catch (Exception e) {
			input.close();
		}
	}

	public static String BFS(int[][] labyrinth, int row, int column) {
		int[][] stepArr = { { -1, 0 }, { 0, 1 }, { 0, -1 }, { 1, 0 } };
		String[] direction = { "U", "R", "L","D"}; 
		int[][] visit = new int[row][column];// 标记是否已经访问过
		StringBuilder sb = new StringBuilder();
		Node node = new Node(0, 0, -1, -1, 0, null);
		Queue<Node> queue = new LinkedList<Node>();
		Stack<Node> stack = new Stack<Node>();
		queue.offer(node);
		while (!queue.isEmpty()) {
			Node head = queue.poll();
			stack.push(head); // 用于回溯路径
			visit[head.x][head.y] = 1;
			for (int i = 0; i < 4; i++) {
				int x = head.x + stepArr[i][0];
				int y = head.y + stepArr[i][1];
				String d = direction[i];
				// exit
				if (x == row - 1 && y == column - 1 && labyrinth[x][y] == 0 && visit[x][y] == 0) {
					// 打印路径
					Node top = stack.pop();
					sb.append(d);
					sb.append(top.direction);
					int preX = top.preX;
					int preY = top.preY;
					while (!stack.isEmpty()) {
						top = stack.pop();
						if (preX == top.x && preY == top.y) {
							if (top.direction != null)
								sb.append(top.direction);
							preX = top.preX;
							preY = top.preY;
						}

					}
					return sb.reverse().toString();
				}
				// bfs
				if (x >= 0 && x < row && y >= 0 && y < column && labyrinth[x][y] == 0 && visit[x][y] == 0) {
					Node newNode = new Node(x, y, head.x, head.y, head.step + 1, d);
					queue.offer(newNode);
				}
			}
		}
		return null;
	}
}

class Node {
	int x, y;
	int step;
	int preX, preY;
	String direction;

	Node(int x, int y, int preX, int preY, int step, String direction) {
		this.x = x;
		this.y = y;
		this.preX = preX;
		this.preY = preY;
		this.step = step;
		this.direction = direction;
	}
}

试题F:特别数的和

import java.util.Scanner;
/** * * @ClassName: SpecialSum特别数的和 * @Description: int转String,使用String.indexOf();判断包含不包含"2", "0", "1", "9",可使用while循环加%,/运算判断。 * @author: colou */
public class SpecialSum特别数的和 {

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			int n = input.nextInt();
			int sum = 0;
			for (int i = 1; i <= n; i++) {
				String target = Integer.toString(i);
				if (target.indexOf("2") != -1 || target.indexOf("0") != -1 || target.indexOf("1") != -1
						|| target.indexOf("9") != -1) {
					sum += i;
				}
			}
			System.out.println(sum);
		} catch (Exception e) {
			input.close();
		}
	}
}

试题G:外卖店优先级

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

/** * @ClassName: TakeawayShopPriority外卖店优先级 * @Description: 建立一个记录店铺优先级的数组来存储优先级,另外建立一个用来判断每一个时间点是否有订单的数组(1表明有 ,0无) * 这里偷懒使用集合充当缓存,可使用数组之类的。 * @author: colou */
public class TakeawayShopPriority外卖店优先级 {

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			Set<Integer> set = new HashSet<Integer>();
			int N = input.nextInt();
			int M = input.nextInt();
			int T = input.nextInt();
			int[][] orders = new int[M][2];
			for (int i = 0; i < M; i++) {
				for (int j = 0; j < 2; j++) {
					orders[i][j] = input.nextInt();
				}
			}
			int[] priority = new int[N];
			int[] sign = new int[N];
			for (int i = 1; i <= T; i++) {
				for (int j = 0; j < M; j++) {
					if (orders[j][0] == i) {
						priority[orders[j][1] - 1] += 2;
						if (priority[orders[j][1] - 1] > 5 && !set.contains(orders[j][1] - 1)) {
							set.add(orders[j][1] - 1);
						}
						sign[orders[j][1] - 1] = 1;
					}
				}
				for (int j = 0; j < N; j++) {
					if (sign[j] == 0 && priority[j] > 0)
						priority[j]--;
					if (priority[j] <= 3) {
						set.remove(j);
					}
				}
				sign = new int[N];
			}
			System.out.println(set.size());
		} catch (Exception e) {
			input.close();
		}
	}
}

试题H:人物相关性分析

import java.util.Scanner;
/** * * @ClassName: CharacterCorrelationAnalysis人物相关性分析 * @Description: "."和"|"都是转义字符,必须得加"\\"; * @author: colou */
public class CharacterCorrelationAnalysis人物相关性分析 {

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			int K = input.nextInt();
			input.nextLine();
			String text = input.nextLine();
			//字符串分割,按照空格和.分割字符,如果(.空格)分割后为空字符串。
			String[] words = text.split("\\s+|\\.");
			int[] wordsLength = new int[words.length];
			//将分割的字符串的长度值存储,避免三重循环中调用String.length();
			for (int i = 0; i < words.length; i++) {
				wordsLength[i] = words[i].length();
			}
			int num = 0;
			//Alice ——> Bob的距离
			for (int i = 0; i < words.length; i++) {
				if (words[i].equals("Alice")) {
					for (int j = i + 1; j < words.length; j++) {
						int sum = 1;
						if (words[j].equals("Bob")) {
							for (int k = i + 1; k < j; k++) {
								//每一个单词的长度加空格占据的长度
								sum += wordsLength[k] + 1;
							}
							if (sum <= K) {
								num++;
							}
						}
					}
				}
			}
			//Bob ——> Alice的距离
			for (int i = 0; i < words.length; i++) {
				if (words[i].equals("Bob")) {
					for (int j = i + 1; j < words.length; j++) {
						int sum = 1;
						if (words[j].equals("Alice")) {
							for (int k = i + 1; k < j; k++) {
								sum += wordsLength[k] + 1;
							}
							if (sum <= K) {
								num++;
							}
						}
					}
				}
			}
			System.out.println(num);
		} catch (Exception e) {
			input.close();
		}
	}
}

试题I:后缀表达式

import java.util.Arrays;
import java.util.Scanner;

/** * @ClassName: PostfixExpression后缀表达式 * @Description: 这道题个人思想是分状况讨论: * 1.若是只有+号,没有-号,则遍历数组累加便可; * 2.若是只有-号,没有+号,首先从小到大排序,而后分两种状况考虑: * (1).最小值是负数(也就是含有负数),例如[-2, -1, 3, 4, 5],四个减号,运算过程为5 - (-1) - (-2 - 3 - 4) = 5 + 1 - (-9) * = 5 + 1 + 9 = 15,也就是说只要含有负数,负数转正数,所有相加便可 * (2).最小值是正数(所有是正数),例如[1, 2, 3],两个减号,运算过程为3 - (1 - 2) = 3 + 2 - 1,也就是说运算规则为除了 * 最小值之外的正数相加减去最小值 * 3.若是有+号,有-号,则讨论减号的个数与负数的个数,分两种状况讨论(实际分为三种): *( 1).减号个数大于等于负数个数(则将负数变正数,每个负数变正数的过程当中, 减号的数量须要减一,而后排序,遍历数组从大到小累加, * 直至剩下的数字个数和减号数量相同,而后再减去这些剩下的数字); * (2).减号个数小于负数个数,这个时候咱们就应该使用+号,消除负数(好比[2, -5 , -6, + , -],运算过程为2 - ((-5) + (-6)) = * 2 + 11 = 13),咱们能够再分状况讨论: * (2.1).全是负数,如[-1, -2, -3, -4, -5],其中一个加号三个减号,运算过程为(-1 - ((-4) + (-5)) - (-3) - (-2) = -1 + 9 * + 3 + 2),则运算规律为首先排序选择其中的最大值,加上其余数字的绝对值就行(能够自行继续证实)。(2.2).有正数,有负数, * [-1, 19, 17, -4, -5],其中两个加号两个减号,则运算过程为(19 + 17 - ((-4) + (-5)) - (-1) = 19 + 17 + 9 + 1),则运算 * 规律为首先排序选择其中的最大值,加上其余数字的绝对值就行(能够自行继续证实)。全部状况讨论完毕。 * @author: colou */
public class PostfixExpression后缀表达式 {

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		try {
			int add = input.nextInt();
			int reduce = input.nextInt();
			int totalLength = add + reduce + 1;
			int[] number = new int[totalLength];
			for (int i = 0; i < totalLength; i++) {
				number[i] = input.nextInt();
			}
			int sum = 0;
			if (reduce == 0) {
				for (int i = 0; i < totalLength; i++) {
					sum += number[i];
				}
			}
			if (add == 0) {
				Arrays.sort(number);
				if (number[0] < 0) {
					for (int i = 0; i <= reduce; i++) {
						if (number[i] > 0) 
							sum += number[i];
						else
							sum -= number[i];
					}
				} else {
					for (int i = 1; i <= reduce; i++) {
							sum += number[i];
					}
					sum -= number[0];
				}
			}
			if (add != 0 && reduce != 0) {
				int reduceNum = 0;
				for (int i = 0; i < totalLength; i++) {
					if (number[i] < 0) {
						reduceNum++;
					}
				}
				if (reduce >= reduceNum) {
					Arrays.sort(number);
					int temp = reduce;
					for (int i = 0; i < reduceNum; i++) {
						number[i] = -number[i];
						temp--;
					}
					Arrays.sort(number);
					for (int i = totalLength - 1; i >= temp; i--) {
						sum += number[i];
					}
					for (int i = temp - 1; i >= 0; i--) {
						sum -= number[i];
					}
				} else {
					Arrays.sort(number);
					sum += number[totalLength - 1];
					for (int i = 0; i < totalLength - 1; i++) {
						if (number[i] > 0)
							sum += number[i];
						else
							sum -= number[i];
					}
				}
			}
			System.out.println(sum);
		} catch (Exception e) {
			input.close();
		}
	}
}

至此完毕,最后一题想偷个懒,等看了以后再更新,若是有错误,请阅读者评论指出,不胜感激。缓存