第十三届蓝桥杯大赛软件赛决赛(Java 大学A组)

本文探讨了信息技术领域中的关键问题,包括二叉树的最大匹配边数计算、数据结构与算法在图书馆借阅管理中的应用,以及大数据项目的需求分析。通过实例演示和组合数学方法,解析了如何在预算约束下优化资源分配和匹配算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


  先做做 CB


试题 A: 火柴棒数字

本题总分: 5 5 5


【问题描述】

  小蓝最近迷上了用火柴棒拼数字字符,方法如下图所示 : :

  他只能拼 0 0 0 9 9 9 这十种数字字符,其中每个数字字符需要的火柴棒的数目依次是 : : 6 , 2 , 5 , 5 , 4 , 5 , 6 , 3 , 7 , 6 6,2,5,5,4,5,6,3,7,6 6,2,5,5,4,5,6,3,7,6。他不喜欢重复拼同一个数字字符,所以对于每个数字字符他最多拼十个。小蓝会把拼出来的数字字符组合在一起形成一个整数, 例如对于整数 345 345 345,需要的火柴棒的数目为 5 + 4 + 5 = 14 5 + 4 + 5 = 14 5+4+5=14 根。小蓝有 300 300 300 根火柴棒,他想知道自己能拼出的最大整数是多少?可以不使用完这 300 300 300 根火柴棒,可以有多余的火柴棒剩下。

【答案提交】

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个由大写字母组成的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。


9999999999777777777755555555554444444444333333333322222222221111111111


多重背包


  将数字视作价值为 1 1 1 且各有 10 10 10 个的物品,需要的火柴棒视作其重量,这显然是个多重背包问题。

  不采用滚动数组以便还原组合方案,在还原方案的时候优先输出尽可能多的,值较大的数字即可。

public class Test {
   

	public static void main(String[] args) {
    new Test().run(); }
	
	int N = 300, W[] = {
    0,6,2,5,5,4,5,6,3,7,6 };
	
	void run() {
   
		int[][] dp = new int[11][N + 1];
		for (int i = 1; i <= 10; ++i)
			for (int k = 0; k <= 10; ++k)
				for (int j = k * W[i]; j <= 300; ++j)
					dp[i][j] = max(dp[i][j], dp[i - 1][j - k * W[i]] + k);
		for (int i = 10, j = 300, k = 0; i > 0; --i, k = 0) {
   
			for (int g = 1; g <= 10 && j - g * W[i] >= 0; ++g)
				if (dp[i][j] <= dp[i - 1][j - g * W[i]] + g) k = g;
			for (j -= k * W[i]; k > 0; --k) System.out.print(i - 1);
		}
	}
	
	int max(int arg1, int arg2) {
    return arg1 > arg2 ? arg1 : arg2; }
}

试题 B: 小蓝与钥匙

本题总分: 5 5 5


【问题描述】

  小蓝是幼儿园的老师,他的班上有 28 28 28 个孩子,今天他和孩子们一起进行了一个游戏。

  小蓝所在的学校是寄宿制学校, 28 28 28 个孩子分别有一个自己的房间,每个房间对应一把钥匙,每把钥匙只能打开自己的门。现在小蓝让这 28 28 28 个孩子分别将自己宿舍的钥匙上交,再把这 28 28 28 把钥匙随机打乱分给每个孩子一把钥匙,有 28 ! = 28 × 27 × ⋯ × 1 28! = 28×27×\cdots×1 28!=28×27××1 种分配方案。小蓝想知道这些方案中,有多少种方案恰有一半的孩子被分到自己房间的钥匙(即有 14 14 14 个孩子分到的是自己房间的钥匙,有 14 14 14 个孩子分到的不是自己房间的钥匙)。

【答案提交】

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


1286583532342313400


组合数学


   28 28 28 个孩子中,任选 14 14 14 个孩子拿到自己房间钥匙的组合数乘以第 14 14 14 个错位排列数,即 C 28 14 × D 14 C_{28}^{14} \times D_{14} C2814×D14 就是我们所要提交的答案。

public class Test {
   

    public static void main(String[] args) {
    new Test().run(); }

    void run() {
    System.out.println(C(28, 14) * D(14)); }

    long C(int n, int m) {
   
        if (m > n || n < 0) return 0;
        if (n == m) return 1;
        return C(n - 1, m) + C(n - 1, m - 1);
    }

    long D(int n) {
   
        if (n == 1) return 0;
        if (n == 2) return 1;
        return (n - 1) * (D(n - 1) + D(n - 2));
    }
}

试题 C: 内存空间

时间限制: 3.0 s 3.0\mathrm s 3.0s 内存限制: 512.0 M B 512.0\mathrm{MB} 512.0MB 本题总分: 10 10 10


【问题描述】

  小蓝最近总喜欢计算自己的代码中定义的变量占用了多少内存空间。

  为了简化问题,变量的类型只有以下三种:

   i n t : \mathrm{int}: int整型变量,一个 i n t \mathrm{int} int 型变量占用 4   B y t e 4\ \mathrm{Byte} 4 Byte 的内存空间。
   l o n g : \mathrm{long}: long长整型变量,一个 l o n g \mathrm{long} long 型变量占用 8   B y t e 8\ \mathrm{Byte} 8 Byte 的内存空间。
   S t r i n g : \mathrm{String}: String字符串变量,占用空间和字符串长度有关,设字符串长度为 L L L,则字符串占用 L   B y t e L\ \mathrm{Byte} L Byte 的内存空间,如果字符串长度为 0 0 0 则占用 0   B y t e 0\ \mathrm{Byte} 0 Byte 的内存空间。

  定义变量的语句只有两种形式,第一种形式为 : :

t y p e   v a r 1 = v a l u e 1 ,   v a r 2 = v a l u e 2 ⋯   ; \mathrm{type\ var1=value1},\ \mathrm{var2=value2}\cdots; type var1=value1, var2=value2;

  定义了若干个 t y p e \mathrm{type} type 类型变量 v a r 1 \mathrm{var1} var1 v a r 2 \mathrm{var2} var2 ⋯ \cdots ,并且用 v a l u e 1 \mathrm{value1} value1 v a l u e 2 ⋯ \mathrm{value2}\cdots value2 初始化,

  多个变量之间用 ’ , ’ ’,’ , 分隔,语句以 ’ ; ’ ’;’ ; 结尾, t y p e \rm type type 可能是 i n t \rm int int l o n g \rm long long S t r i n g \rm String String。例如 i n t a = 1 ,   b = 5 ,   c = 6 ; \rm int a=1,\ b=5,\ c=6; inta=1, b=5, c=6; 占用空间为 12   B y t e 12\ \rm Byte 12 Byte l o n g   a = 1 ,   b = 5 ; \rm long\ a=1,\ b=5; long a=1, b=5; 占用空间为 16   B y t e 16\ \rm Byte 16 Byte S t r i n g   s 1 = ”” ,   s 2 = ” h e l l o ” ,   s 3 = ” w o r l d ” ; \rm String \ s1=””,\ s2=”hello”,\ s3=”world”; String s1=””, s2=”hello”, s3=”world”; 占用空间为 10   B y t e 10\ \rm Byte 10 Byte

  第二种形式为 : :

t y p e [   ]   a r r 1 = n e w   t y p e [ s i z e 1 ] , a r r 2 = n e w   t y p e [ s i z e 2 ] ⋯   ; \rm type[\:]\ arr1=new\ type[size1],arr2=new\ type[size2]\cdots; type[] arr1=new type[size1],arr2=new type[size2];

  定义了若干 t y p e \rm type type 类型的一维数组变量 a r r 1 \rm arr1 arr1 a r r 2 ⋯ \rm arr2\cdots arr2,且数组的大小为 s i z e 1 \rm size1 size1 s i z e 2 ⋯ \rm size2\cdots size2,多个变量之间用 ’ , ’ ’,’ , 进行分隔,语句以 ’ ; ’ ’;’ ; 结尾, t y p e \rm type type 只可能是 i n t \rm int int l o n g \rm long long。例如 i n t [   ]   a 1 = n e w   i n t [ 10 ] ; \rm int[\:]\ a1=new\ int[10]; int[] a1=new int[10]; 占用的内存空间为 40   B y t e 40\ \rm Byte 40 Byte l o n g [   ]   a 1 = n e w   l o n g [ 10 ] ,   a 2 = n e w   l o n g [ 10 ] ; \rm long[\:]\ a1=new\ long[10],\ a2=new\ long[10]; long[] a1=new long[10], a2=new long[10]; 占用的内存空间为 160   B y t e 160\ \rm Byte 160 Byte

  已知小蓝有 T T T 条定义变量的语句,请你帮他统计下一共占用了多少内存空间。结果的表示方式为 : : a G B b M B c K B d B a\mathrm{GB}b\mathrm{MB}c\mathrm{KB}d\mathrm B aGBbMBcKBdB,其中 a a a b b b c c c d d d 为统计的结果, G B \rm GB GB M B \rm MB MB K B \rm KB KB B \rm B B 为单位。优先用大的单位来表示, 1 G B = 1024 M B \rm 1GB=1024MB 1GB=1024MB 1 M B = 1024 K B \rm 1MB=1024KB 1MB=1024KB 1 K B = 1024 B \rm 1KB=1024B 1KB=1024B,其中 B B B 表示 B y t e \rm Byte Byte。如果 a a a b b b c c c d d d 中的某几个数字为 0 0 0,那么不必输出这几个数字及其单位。题目保证一行中只有一句定义变量的语句,且每条语句都满足题干中描述的定义格式,所有的变量名都是合法的且均不重复。题目中的数据很规整,和上述给出的例子类似,除了类型后面有一个空格,以及定义数组时 n e w \rm new new 后面的一个空格之外,不会出现多余的空格。

【输入格式】

  输入的第一行包含一个整数 T T T ,表示有 T T T 句变量定义的语句。

  接下来 T T T 行,每行包含一句变量定义语句。

【输出格式】

  输出一行包含一个字符串,表示所有语句所占用空间的总大小。

【样例输入 1】

1
long[] nums=new long[131072];

【样例输出 1】

1MB

【样例输入 2】

4
int a=0,b=0;
long x=0,y=0;
String s1="hello",s2="world";
long[] arr1=new long[100000],arr2=new long[100000];

【样例输出 2】

1MB538KB546B

【样例说明】
 样例 1 1 1,占用的空间为 131072 × 8 = 1048576   B 131072×8 = 1048576\ \mathrm B 131072×8=1048576 B,换算过后正好是 1   M B 1\ \rm MB 1 MB,其 它三个单位 G B \rm GB GB K B \rm KB KB B \rm B B 前面的数字都为 0 0 0 ,所以不用输出。
 样例 2 2 2,占用的空间为 4 × 2 + 8 × 2 + 10 + 8 × 100000 × 2   B 4×2 + 8×2 + 10 + 8×100000×2 \mathrm\ B 4×2+8×2+10+8×100000×2 B,换算后是 1 M B 538 K B 546 B 1\mathrm{MB}538\mathrm{KB}546\mathrm B 1MB538KB546B

【评测用例规模与约定】

  对于所有评测用例, 1 ≤ T ≤ 10 1 ≤ T ≤ 10 1T10,每条变量定义语句的长度不会超过 1000 1000 1000。所有的变量名称长度不会超过 10 10 10,且都由小写字母和数字组成。对于整型变 量,初始化的值均是在其表示范围内的十进制整数,初始化的值不会是变量。 对于 S t r i n g \rm String String 类型的变量,初始化的内容长度不会超过 50 50 50,且内容仅包含小写字母和数字,初始化的值不会是变量。对于数组类型变量,数组的长度为一个 整数,范围为 : : [ 0 , 2 30 ] [0,2^{30}] [0,230],数组的长度不会是变量。 T T T 条语句定义的变量所占的内存空间总大小不会超过 1   G B 1\ \rm GB 1 GB,且大于 0   B 0\ \rm B 0 B


  挨喷题。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
   
	
	public static void main(String[] args) {
    new Main().run(); }
	
	String[] unit = {
    "", "K", "M", "G" };
	
	void run() {
   
		long count = 0;
		try (BufferedReader in = new BufferedReader(new InputStreamReader(System.in))) {
   
			for (int T = Integer.parseInt(in.readLine()); T-- > 0;) {
   
				String line = in.readLine();
				if (line.startsWith("String")) {
   
					for (int flag = 0, i = 0, j = 0; i < line.length(); ++i) {
   
						if (line.charAt(i) == '"') {
   
							count += flag * (i - j - 1);
							flag ^= 1;
							j = i;
						}
					}
				} else {
   
					long buffer = 0;
					if (line.charAt(3) == '[' || line.charAt(4) == '[')
						for (int i = 6, j = 0; i < line.length(); ++i) {
   
							if (line.charAt(i) == '[') j = i;
							else if (line.charAt(i) == ']')
								buffer += Integer.parseInt(line.substring(j + 1, i));
						}
					else buffer = line.split(",").length;
					count += buffer << (line.startsWith("int") ? 2 : 3);
				}
			}
		} catch (IOException e) {
   
			e.printStackTrace();
		}
		for (int i = 3; i >= 0; --i)
			if (count >> (i * 10) > 0) {
   
				System.out.print((count >> (i * 10)) + unit[i] + 'B');
				count &= (1 << (i * 10)) - 1;
			}
	}
}

试题 D: 斐波那契数组

时间限制: 3.0 s 3.0\mathrm s 3.0s 内存限制: 512.0 M B 512.0\mathrm{MB} 512.0MB 本题总分: 10 10 10


【问题描述】

  如果数组 A = ( a 0 , a 1 , ⋯   , a n − 1 ) A = (a_0,a_1,\cdots ,a_{n−1}) A=(a0,a1,,an1) 满足以下条件,就说它是一个斐波那契数组 : :

   1. 1. 1. n ≥ 2 n≥2 n2
   2. 2. 2. a 0 = a 1 a_0 = a_1 a0=a1
   3. 3. 3. 对于所有的 i ( i ≥ 2 ) i(i≥2) i(i2),都满足 a i = a i − 1 + a i − 2 a_i = a_{i−1} + a_{i−2} ai=ai1+ai2

  现在,给出一个数组 A A A ,你可以执行任意次修改,每次修改将数组中的某个位置的元素修改为一个大于 0 0 0 的整数。请问最少修改几个元素之后,数组 A A A 会变成一个斐波那契数组。

【输入格式】

  输入的第一行包含一个整数 n n n,表示数组 A A A 中的元素个数。

  第二行包含 n n n 个整数 a 0 , a 1 , ⋯   , a n − 1 a_0,a_1, \cdot

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值