2019 第十屆藍橋杯Java省賽B組個人題解

2019 第十屆藍橋杯Java省賽B組個人題解

前言

  以下的第十屆藍橋杯Java B組省賽的題目題解只是我個人的題解,提供一些解題思路,僅作參考,如有錯誤,望大家指出,不勝感激,我會及時更改。

  本來想把比賽題目上傳到CSDN上免費下載,上傳之後發現默認是5積分(根據下載熱度和評星積分會自己調整),後來瞭解到現在的CSDN向知識付費靠攏,激勵用戶上傳資源,取消了用戶自行定價的功能和下架資源的功能(需要找客服下架,客服根本不理啊)。
PS:CSDN可能是看到這個文章了嗎?題目可以免費下載了,0積分了,棒!!!

  2019 第十屆藍橋杯Java省賽B組題目——CSDN(需要5或者更多積分(系統自己調的),希望大家儘量下載下面鏈接的,誰的積分來的都不容易)

  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();
		}
	}
}

至此完畢,最後一題想偷個懶,等看了之後再更新,如果有錯誤,請閱讀者評論指出,不勝感激。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章