蓝桥杯 2022年省赛真题
Java 大学C组
很难避免,需要在错误中成长的困境。
毕竟人都是向下望就变得能坚强,
我亦尔耳。
试题 A: 排列字母
本题总分: 5 5 5 分
【问题描述】
小蓝要把一个字符串中的字母按其在字母表中的顺序排列。
例如, L A N Q I A O \mathrm{LANQIAO} LANQIAO 排列后为 A A I L N O Q \mathrm{AAILNOQ} AAILNOQ。
又如, G O O D G O O D S T U D Y D A Y D A Y U P \mathrm{GOODGOODSTUDYDAYDAYUP} GOODGOODSTUDYDAYDAYUP 排列后为 A A D D D D D G G O O O O P S T U U Y Y Y \mathrm{AADDDDDGGOOOOPSTUUYYY} AADDDDDGGOOOOPSTUUYYY。
请问对于以下字符串,排列之后字符串是什么?
W H E R E T H E R E I S A W I L L T H E R E I S A W A Y \mathrm{WHERETHEREISAWILLTHEREISAWAY} WHERETHEREISAWILLTHEREISAWAY
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个由大写字母组成的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。
public class Test {
public static void main(String[] args) {
java.util.Arrays.stream("WHERETHEREISAWILLTHEREISAWAY".split("")).sorted().forEach(System.out::print);
}
}
整个活。
试题 B: 特殊时间
本题总分: 5 5 5 分
【问题描述】
2022 2022 2022 年 2 2 2 月 22 22 22 日 22 22 22: 20 20 20 是一个很有意义的时间,年份为 2022 2022 2022,由 3 3 3 个 2 2 2 和 1 1 1 个 0 0 0 组成,如果将月和日写成 4 4 4 位,为 0222 0222 0222,也是由 3 3 3 个 2 2 2 和 1 1 1 个 0 0 0 组成,如果将时间中的时和分写成 4 4 4 位,还是由 3 3 3 个 2 2 2 和 1 1 1 个 0 0 0 组成。
小蓝对这样的时间很感兴趣,他还找到了其它类似的例子,比如 111 111 111 年 10 10 10 月 11 11 11 日 01 01 01: 11 11 11, 2202 2202 2202 年 2 2 2 月 22 22 22 日 22 22 22: 02 02 02 等等。
请问,总共有多少个时间是这种年份写成 4 4 4 位、月日写成 4 4 4 位、时间写成 4 4 4 位后由 3 3 3 个一种数字和 1 1 1 个另一种数字组成。注意 1111 1111 1111 年 11 11 11 月 11 11 11 日 11 11 11: 11 11 11 不算,因为它里面没有两种数字。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
在 3 3 3 个相同的个位数中插入 1 1 1 个个位数,显然可以组成 4 4 4 个不同的数字(不一定是 4 4 4 位数),于是我们可以另一个合法的 月日时分 与 4 4 4 个不同的年份组成映射关系,只要统计出合法的 日月时分 个数,将其乘上一个 4 4 4,答案就被计算出来了。
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
public class Test {
public static void main(String[] args) { new Test().run(); }
void run() {
DateTimeFormatter date = DateTimeFormatter.ofPattern("MMdd");
DateTimeFormatter time = DateTimeFormatter.ofPattern("HHmm");
LocalDateTime start = LocalDateTime.of(0000, 01, 01, 00, 00);
LocalDateTime end = LocalDateTime.of(0000, 12, 31, 23, 59);
int[] buff = new int[128];
int ans = 0;
for (; start.compareTo(end) <= 0; start = start.plusMinutes(1)) {
for (char i = '0'; i <= '9'; ++i) buff[i] = 0;
for (byte b : start.format(date).getBytes()) ++buff[b];
boolean flag1 = true, flag3 = true;
for (char i = '0'; i <= '9'; ++i)
if (buff[i] == 1) flag1 = false;
else if (buff[i] == 3) flag3 = false;
if (flag1 || flag3) continue;
for (byte b : start.format(time).getBytes()) --buff[b];
for (char i = '0'; i <= '9'; ++i)
if (buff[i] != 0) flag1 = true;
if (!flag1) ++ans;
}
System.out.println(4 * ans);
}
}
试题 C: 纸张尺寸
时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 512.0 M B 512.0\mathrm{MB} 512.0MB 本题总分: 10 10 10 分
【问题描述】
在 I S O \mathrm{ISO} ISO 国际标准中定义了 A 0 \mathrm A0 A0 纸张的大小为 1189 m m × 841 m m 1189\mathrm{mm} × 841\mathrm{mm} 1189mm×841mm,将 A 0 \mathrm A0 A0 纸沿长边对折后为 A 1 \mathrm A1 A1 纸,大小为 841 m m × 594 m m 841\mathrm{mm} × 594\mathrm{mm} 841mm×594mm,在对折的过程中长度直接取下整(实际裁剪时可能有损耗)。将 A 1 \mathrm A1 A1 纸沿长边对折后为 A 2 \mathrm A2 A2 纸,依此类推。
输入纸张的名称,请输出纸张的大小。
【输入格式】
输入一行包含一个字符串表示纸张的名称,该名称一定是 A 0 \mathrm A0 A0、 A 1 \mathrm A1 A1、 A 2 \mathrm A2 A2、 A 3 \mathrm A3 A3、 A 4 \mathrm A4 A4、 A 5 \mathrm A5 A5、 A 6 \mathrm A6 A6、 A 7 \mathrm A7 A7、 A 8 \mathrm A8 A8、 A 9 \mathrm A9 A9 之一。
【输出格式】
输出两行,每行包含一个整数,依次表示长边和短边的长度。
【样例输入 1】
A0
【样例输出 1】
1189
841
【样例输入 2】
A1
【样例输出 2】
841
594
签到题,
J
a
v
a
8
\mathrm{Java}\ 8
Java 8 支持 switch
String
对象,
直接用 switch
的特性写了。
import java.util.Scanner;
public class Main {
public static void main(String[] args) { new Main().run(); }
int length = 1189, wide = 841;
void cut() {
int temp = wide;
wide = length / 2;
length = temp;
}
void run() {
switch (new Scanner(System.in).next()) {
case "A9": cut();
case "A8": cut();
case "A7": cut();
case "A6": cut();
case "A5": cut();
case "A4": cut();
case "A3": cut();
case "A2": cut();
case "A1": cut();
default: System.out.printf("%d\n%d", length, wide);
}
}
}
试题 D: 求和
时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 512.0 M B 512.0\mathrm{MB} 512.0MB 本题总分: 10 10 10 分
【问题描述】
给定 n n n 个整数 a 1 , a 2 , ⋯ , a n a_1, a_2, \cdots , a_n a1,a2,⋯,an,求它们两两相乘再相加的和,即 S = a 1 ⋅ a 2 + a 1 ⋅ a 3 + ⋯ + a 1 ⋅ a n + a 2 ⋅ a 3 + ⋯ + a n − 2 ⋅ a n − 1 + a n − 2 ⋅ a n + a n − 1 ⋅ a n 。 S = a_1\cdot a_2 + a_1\cdot a_3 + \cdots + a_1\cdot a_n + a_2\cdot a_3 +\cdots + a_{n−2}\cdot a_{n−1} + a_{n−2}\cdot a_n + a_{n−1}\cdot a_n。 S=a1⋅a2+a1⋅a3+⋯+a1⋅an+a2⋅a3+⋯+an−2⋅an−1+an−2⋅an+an−1⋅an。
【输入格式】
输入的第一行包含一个整数 n n n 。
第二行包含 n n n 个整数 a 1 , a 2 , ⋯ , a n a_1, a_2,\cdots,a_n a1,a2,⋯,an。
【输出格式】
输出一个整数 S S S,表示所求的和。请使用合适的数据类型进行运算。
【样例输入】
4
1 3 6 9
【样例输出】
117
【评测用例规模与约定】
对于
30
%
30\%
30% 的数据,
1
≤
n
≤
1000
,
1
≤
a
i
≤
100
1 ≤ n ≤ 1000,1 ≤ a_i ≤ 100
1≤n≤1000,1≤ai≤100。
对于所有评测用例,
1
≤
n
≤
200000
,
1
≤
a
i
≤
1000
1 ≤ n ≤ 200000,1 ≤ a_i ≤ 1000
1≤n≤200000,1≤ai≤1000。
公式递推
将 S S S 中包含 a 1 a_1 a1 的项整理出来,有:
S = a 1 ⋅ ( a 2 + a 3 + ⋯ + a n ) + a 2 ⋅ a 3 + ⋯ + a n − 2 ⋅ a n − 1 + a n − 2 ⋅ a n + a n − 1 ⋅ a n S=a_1\cdot(a_2+a_3+\cdots+a_n)+ a_2\cdot a_3 +\cdots + a_{n−2}\cdot a_{n−1} + a_{n−2}\cdot a_n + a_{n−1}\cdot a_n S=a1⋅(a2+a3+⋯+an)+a2⋅a3+⋯+an−2⋅an−1+an−2⋅an+an−1⋅an
同样的将余项中包含 a 2 a_2 a2、 a 3 a_3 a3、 ⋯ \cdots ⋯、 a n a_n an 的项整理出来:
S = a 1 ⋅ ( a 2 + a 3 + ⋯ + a n ) + a 2 ⋅ ( a 3 + a 4 + ⋯ + a n ) + ⋯ + a n − 1 ⋅ a n = a 1 ⋅ ∑ i = 2 n a i + a 2 ⋅ ∑ i = 3 n a i + ⋯ + a n − 1 ⋅ ∑ i = n n a i \begin{aligned}S&=a_1\cdot(a_2+a_3+\cdots+a_n)+ a_2\cdot(a_3+a_4+\cdots+a_n)+\cdots+a_{n-1}\cdot a_n\\&=a_1\cdot\sum_{i=2}^na_i+a_2\cdot \sum_{i=3}^na_i+\cdots+a_{n-1}\cdot\sum_{i=n}^{n}a_i\end{aligned} S=a1⋅(a2+a3+⋯+an)+a2⋅(a3+a4+⋯+an)+⋯+an−1⋅an=a1⋅i=2∑nai+a2⋅i=3∑nai+⋯+an−1⋅i=n∑nai
也就 S S S 等于每个元素乘以右边所有元素的和的和,考虑到实现计算的代码量,我们将 S S S 的项重排,重新整理出:
S = a 1 ⋅ ∑ i = 1 0 a i + a 2 ⋅ ∑ i = 1 1 a i + ⋯ + a n ⋅ ∑ i = 1 n − 1 a i S=a_1\cdot\displaystyle\sum_{i=1}^{0}a_i+a_2\cdot \sum_{i=1}^{1}a_i+\cdots+a_{n}\cdot\sum_{i=1}^{n-1}a_i S=a1⋅i=1∑0ai+a2⋅i=1∑1ai+⋯+an⋅i=1∑n−1ai
import java.io.StreamTokenizer;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) { new Main().run(); }
void run() {
int n = nextInt(), sum = 0;
long a, ans = 0;
while(n-- > 0) {
a = nextInt();
ans += a * sum;
sum += a;
}
System.out.println(ans);
}
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
int nextInt() {
try {
in.nextToken();
} catch (IOException e) {
e.printStackTrace();
}
return (int)in.nval;
}
}
试题 E: 矩形拼接
时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 512.0 M B 512.0\mathrm{MB} 512.0MB 本题总分: 15 15 15 分
【问题描述】
已知 3 3 3 个矩形的大小依次是 a 1 × b 1 a_1 × b_1 a1×b1、 a 2 × b 2 a_2 × b_2 a2×b2 和 a 3 × b 3 a_3 × b_3 a3×b3。用这 3 3 3 个矩形能拼出的所有多边形中,边数最少可以是多少?
例如用 3 × 2 3 × 2 3×2 的矩形(用 A \mathrm A A 表示)、 4 × 1 4 × 1 4×1 的矩形(用 B \mathrm B B 表示)和 2 × 4 2 × 4 2×4 的矩形(用 C \mathrm C C 表示)可以拼出如下 4 4 4 边形。
例如用
3
×
2
3 × 2
3×2 的矩形(用
A
\mathrm A
A 表示)、
3
×
1
3 × 1
3×1 的矩形(用
B
\mathrm B
B 表示)和
1
×
1
1 × 1
1×1 的矩形(用
C
\mathrm C
C 表示)可以拼出如下
6
6
6 边形。
【输入格式】
输入包含多组数据。
第一行包含一个整数 T T T,代表数据组数。
以下 T T T 行,每行包含 6 6 6 个整数 a 1 , b 1 , a 2 , b 2 , a 3 , b 3 a_1, b_1, a_2, b_2, a_3, b_3 a1,b1,a2,b2,a3,b3,其中 a 1 , b 1 a_1, b_1 a1,b1 是第一个矩形的边长, a 2 , b 2 a_2, b_2 a2,b2 是第二个矩形的边长, a 3 , b 3 a_3, b_3 a3,b3 是第三个矩形的边长。
【输出格式】
对于每组数据,输出一个整数代表答案。
【样例输入】
2
2 3 4 1 2 4
1 2 3 4 5 6
【样例输出】
4
8
【评测用例规模与约定】
对于
10
%
10\%
10% 的评测用例,
1
≤
T
≤
5
,
1
≤
a
1
,
b
1
,
a
2
,
b
2
,
a
3
,
b
3
≤
10
,
a
1
=
a
2
=
a
3
1 ≤ T ≤ 5,1 ≤ a_1, b_1, a_2, b_2, a_3, b_3 ≤ 10,a_1 = a_2 =a_3
1≤T≤5,1≤a1,b1,a2,b2,a3,b3≤10,a1=a2=a3。
对于
30
%
30\%
30% 的评测用例,
1
≤
T
≤
5
,
1
≤
a
1
,
b
1
,
a
2
,
b
2
,
a
3
,
b
3
≤
10
1 ≤ T ≤ 5,1 ≤ a_1, b_1, a_2, b_2, a_3, b_3 ≤ 10
1≤T≤5,1≤a1,b1,a2,b2,a3,b3≤10。
对于
60
%
60\%
60% 的评测用例,
1
≤
T
≤
10
,
1
≤
a
1
,
b
1
,
a
2
,
b
2
,
a
3
,
b
3
≤
20
1 ≤ T ≤ 10,1 ≤ a_1, b_1, a_2, b_2, a_3, b_3 ≤ 20
1≤T≤10,1≤a1,b1,a2,b2,a3,b3≤20。
对于所有评测用例,
1
≤
T
≤
1000
,
1
≤
a
1
,
b
1
,
a
2
,
b
2
,
a
3
,
b
3
≤
100
1 ≤ T ≤ 1000,1 ≤ a_1, b_1, a_2, b_2, a_3, b_3 ≤ 100
1≤T≤1000,1≤a1,b1,a2,b2,a3,b3≤100。