2019第十届蓝桥杯JAVA B组题目分析

蓝桥杯历年真题及解析.

A:组队(难度:★★★)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

team信息文本:
1 97 90 0 0 0
2 92 85 96 0 0
3 0 0 0 0 93
4 0 0 0 80 86
5 89 83 97 0 0
6 82 86 0 0 0
7 0 0 0 87 90
8 0 97 96 0 0
9 0 0 89 0 0
10 95 99 0 0 0
11 0 0 96 97 0
12 0 0 0 93 98
13 94 91 0 0 0
14 0 83 87 0 0
15 0 0 98 97 98
16 0 0 0 93 86
17 98 83 99 98 81
18 93 87 92 96 98
19 0 0 0 89 92
20 0 99 96 95 81

分析:

先找出第一个位置的球员,做标记。
再找出第二个位置的球员,做标记。
。。。
最后找出第五个位置的球员,做标记。
计算五个做标记球员的sum是多少。
对所有的和取max即为最优解!

代码:

满分

package JB2019;
//490
import java.util.Scanner;
//暴力递归要记得回溯
public class A{
	public static int ans=-1;
	
	public static void qpl(int arr[][],boolean buf[],int k,int cur){
		if(k==6){
			ans=Math.max(ans,cur );
			return;
		}
		for(int i=0;i<20;i++){
			if(buf[i])continue;
			buf[i]=true;
			cur+=arr[i][k];
			qpl(arr,buf,k+1,cur);
			buf[i]=false;
			cur-=arr[i][k];
		}
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int arr[][]=new int[20][6];
		boolean buf[]=new boolean [20];
		for(int i=0;i<20;i++){
			for(int j=0;j<6;j++){
				arr[i][j]=sc.nextInt();
			}
		}
		qpl(arr,buf,1,0);
		System.out.println(ans);
	}
}

B:不同字串(难度:★)

在这里插入图片描述

题目数据01字符串:
0100110001010001

分析:

暴力枚举所有起点&终点。
将中间的字符串放入HashSet去重。
最终HashSet的容量即为ans。

代码:

满分

package JB2019;
//100
import java.util.*;
//SubString 包括begin,不包括end
public class B {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		String s=sc.next();
		HashSet<String> set=new HashSet<String>();
		for(int i=0;i<s.length();i++){
			for(int j=i+1;j<=s.length();j++){
				set.add(s.substring(i,j));
			}
		}
		System.out.println(set.size());
	}
}

C:数列求值(难度:★)

在这里插入图片描述

分析:

此题直接计算即可!
考虑内存不要溢出!

代码:

满分

package JB2019;
//考虑时间会不会过长
//考虑内存会不会溢出
//4659
public class C {
	public static void main(String[] args) {
		int arr[]=new int[20190325];
		arr[1]=1;
		arr[2]=1;
		arr[3]=1;
		for(int i=4;i<20190325;i++){
			arr[i]+=(arr[i-1]+arr[i-2]+arr[i-3]);
			arr[i]%=10000;
		}
		System.out.println(arr[20190324]);
	}
}

D:数的分解:(难度:★★)

在这里插入图片描述

分析:

假设三个整数为 i,j,k 。
我们令 i < j < k 。
再枚举出 i & j ,
通过 k = 2019 - i - j 得出 k。
最终我们check 一下三个数字中是否含有 2 or 4.
如果符合条件即进行计数。

代码:

满分

package JB2019;
//很明显,三层for时间很可能超限
//所以我们用两层,用ans-前两层即第三层
//40785
public class D {
	
	public static boolean check(int n){
		while(n>0){
			if(n%10==2||n%10==4)return false;
			else n/=10;
		}
		return true;
	}
	public static void main(String[] args) {
		int sum=2019;
		int ans=0;
		for(int i=1;i<700;i++){
			sum-=i;
			for(int j=i+1;j<1050;j++){
				sum-=j;
				if(sum>j&&check(i)&&check(j)&&check(sum)){
					ans++;
				}
				sum+=j;
			}
			sum+=i;
		}
		System.out.println(ans);
	}
}

E:迷宫:(难度:★★★★)

在这里插入图片描述

maze.txt文件如下:
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

在这里插入图片描述

分析:

迷宫类型的题目一般用BFS or DFS,
此题询问移动路线,所以我们选择BFS。
为了防止陷入死循环,我们采用一个buf数组用来标记。
每次移动将移动路径记录下来,
当走到终点时,将路线依次与ans相比较。
最终走完所有路径即得到结果。

代码:

满分

package JB2019;
//ans="DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR";

import java.util.HashMap;
import java.util.Scanner;
//范围明确不清晰,m写成了n
//新制代码写完后,没有注释掉原来的代码。
//简洁或的用法,先判断第一个表达式,符合情况即不再判断第二个表达式
//hashMap在装入新的元素时,会把旧元素覆盖。
public class  迷宫{
	public static int n=30,m=50;
	public static char c[][]=new char [n][m];
	public static boolean b[][]=new boolean [n][m];
	public static HashMap<Integer,String> old=new HashMap<Integer,String>();
	public static HashMap<Integer,String> niu=new HashMap<Integer,String>();
	public static String ans="";
	public static boolean BFS(int x,int y,String s){
		boolean ok=false;
		b[x][y]=true;
		for(int i=-1;i<2;i++){
			for(int j=-1;j<2;j++){
				if(Math.abs(i+j)!=1)continue;
				if(i+x<0||j+y<0||i+x>=n||j+y>=m||c[x+i][y+j]=='1'||b[x+i][y+j])continue;//
				int index=(i+x)*100+y+j;
				String ns=s+f(i,j);
				if(niu.containsKey(index)){
					niu.put(index, ns.compareTo(niu.get(index))>0?niu.get(index):ns);
				}else{
					niu.put(index, ns);
				}
				if(i+x==n-1&&j+y==m-1){
					ok=true;
					if(ans.equals("")){
						ans=ns;
					}else{
						ans=(ans.compareTo(ns)>0)?ns:ans;
					}
				}
			}
		}
		
		return ok;
	}
	public static String f(int x,int y){
		if(x==1)return "D";
		else if(x==-1)return "U";
		else if (y==1)return "R";
		else return "L";
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		for(int i=0;i<n;i++){
			c[i]=sc.next().toCharArray();
		}
		old.put(0, "");
		boolean end=false;
		while(!end){
			for(int t:old.keySet()){
				if(BFS(t/100,t%100,old.get(t))){
					end=true;
				}
			}
			old.clear();
			old.putAll(niu);
			niu.clear();
		}
		System.out.println(ans);
	}
}


F:特别数的和:(难度:★★)

在这里插入图片描述
在这里插入图片描述

分析:

从1 ~ n,对每一个数据进行check,
符合条件,即加入ans。
最终运行结束时,ans即为解!

代码:

满分

package JB2019;

import java.util.Scanner;
//暴力排查
public class F {
	public static boolean check(int k){
		while(k>0){
			if(k%10==2||k%10==0||k%10==1||k%10==9){
				return true;
			}
			k/=10;
		}
		return false;
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int ans=0;
		for(int i=1;i<=n;i++){
			if(check(i)){
				ans+=i;
			}
		}
		System.out.println(ans);
	}
}

G:外卖店优先级(难度:★★★)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

【样例输入】
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
【样例输出】
1

分析:

采用邻接表的形式对订单信息进行存储,
然后按照时间顺序模拟订单下单操作。
随时对优先缓存容器进行更新!
《时间复杂度有点莽,答案正确但时间不太稳定》
后续应该还会再进行优化

代码:

测试满分,就看评测姬给不给力了

import java.util.*;
 
public class B外卖店优先级 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            int n=sc.nextInt();
            int m=sc.nextInt();
            int t=sc.nextInt();
            int pro[]=new int[n+1];
            int last[]=new int[n+1];
            HashMap<Integer,Integer> arr[]=new HashMap[t+1];
            for(int i=0;i<=t;i++){
                arr[i]=new HashMap<Integer,Integer>();
            }
            int ts,id;
            for(int i=0;i<m;i++){
                ts=sc.nextInt();
                id=sc.nextInt();
                arr[ts].put(id, arr[ts].getOrDefault(id, 0)+1);
            }
            HashSet<Integer> ans=new HashSet<Integer>();
            for(int i=0;i<=t;i++){
                for(int x:arr[i].keySet()){
                    pro[x]=Math.max(0, pro[x]-(i-last[x]-1));
                    if(pro[x]<=3&&ans.contains(x))ans.remove(x);
                    pro[x]+=arr[i].get(x)*2;
                    if(pro[x]>5&&!ans.contains(x))ans.add(x);
                    last[x]=i;
                }
            }
            for(int i=1;i<=n;i++){
                if(last[i]!=t){
                    pro[i]=Math.max(0, pro[i]-(t-last[i]));
                    if(pro[i]<=3&&ans.contains(i))ans.remove(i);
                }
            }
            System.out.println(ans.size());
        }
    }
}

H:人物相关性分析(难度:★★★★★)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

【样例输入】
20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
【样例输出】
2

分析:

我将所有 Alice 信息储存在 Al 容器内,
将所有 Bob 位置信息纯存在 Bo 容器内,
随后采用差分的方式确定每一个 Alice 的覆盖区间。
再采用前缀和获取每一个坐标对于Bob的QZH收益。

最后遍历Bob的位置信息,通过QZH数组获取收益即可。
最终所有收益的和即为解。

代码:

满分

package JB2019;

import java.util.ArrayList;
import java.util.Scanner;

public class H {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int k = sc.nextInt();
		sc.nextLine();
		String s = sc.nextLine();
		char c[] = s.toCharArray();
		ArrayList<Integer> Al = new ArrayList<Integer>();
		ArrayList<Integer> Bo = new ArrayList<Integer>();
		for (int i = 0; i < c.length; i++) {
			if ((i - 1 < 0 || c[i - 1] == '.' || c[i - 1] == ' ') && c[i] == 'A' && c[i + 1] == 'l' && c[i + 2] == 'i'
					&& c[i + 3] == 'c' && c[i + 4] == 'e' && (c[i + 5] == '.' || c[i + 5] == ' ')) {
				Al.add(i);
			}
		}
		for (int i = 0; i < c.length; i++) {
			if ((i - 1 < 0 || c[i - 1] == '.' || c[i - 1] == ' ') && c[i] == 'B' && c[i + 1] == 'o' && c[i + 2] == 'b'
					&& (c[i + 3] == '.' || c[i + 3] == ' ')) {
				Bo.add(i);
			}
		}

		long ans = 0;
		int CF[] = new int[1000009];
		int QZH[] = new int[1000005];
		for (int t : Al) {
			CF[Math.max(0, t - k - 3)]++;
			CF[Math.min(1000000, t + k + 5)]--;
		}
		QZH[0] = CF[0];
		for (int i = 1; i < 1000005; i++) {
			QZH[i] = QZH[i - 1] + CF[i];
		}
		for (int t : Bo) {
			ans += QZH[t];
		}
		System.out.println(ans);
	}
}

I:后缀表达式(难度:★★★★)

在这里插入图片描述
在这里插入图片描述

【样例输入】
1 1
1 2 3
【样例输出】
4

分析:

这是一个思维题,只需要稍微分析即可得解。
首先,在后缀表达式中虽然没有“()”的存在,
但是在计算过程中,括号还是可以隐性存在的。
举个例子:

输入:
2 7
-1 0 1 2 3 4 5 6 7 8
输出:
37

因为0 - (1-2-3-4-(5+6)-(7+8))=37

我们可以推导出无论何种状态下,我们均可以把所有的后续值变成正值。
我们唯一不确定的即是第一个元素。

我们可以列出表格。
在这里插入图片描述
根据表格进行编码即可。

代码:

满分

package JB2019;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;

public class I {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		ArrayList<Integer> al=new ArrayList<Integer>();
		ArrayList<Integer> z=new ArrayList<Integer>();
		ArrayList<Integer> f=new ArrayList<Integer>();
		
		int x;
		for(int i=0;i<n+m+1;i++){
			x=sc.nextInt();
			al.add(x);
			if(x>0)z.add(x);
			else if(x<0)f.add(x);
			else {
				z.add(x);
				f.add(x);
			}
		}
		long ans=0,sum=0;
		for(int i=0;i<al.size();i++){
			sum+=Math.abs(al.get(i));
		}
		Collections.sort(al);
		Collections.sort(z);
		Collections.sort(f);
		if(m==0&&n==0){
			ans=al.get(0);
		}else if(z.size()>0&&f.size()>0){
			if(n>0&&m==0){
				for(int i=0;i<al.size();i++){
					ans+=al.get(i);
				}
			}else{
				ans=sum;
			}
		}else if(z.size()==0){
			if(n>0&&m==0){
				ans=-sum;
			}else{
				ans=sum+2*f.get(f.size()-1);
			}
		}else{
			if(n>0&&m==0){
				ans=sum;
			}else{
				ans=sum-2*z.get(0);
			}
		}
			System.out.println(ans);
	}
}

G:灵能传输(难度:★★★★★)

这个题目后续更新或者放在交流群里。

写在最后

本文的所有题目的测试数据均放在交流群内。方便大家一起学习交流。
在这里插入图片描述
欢迎大家加QQ群一起玩耍。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王跃坤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值