周六花了一个上午参加了蓝桥杯研究生组的比赛,总体来说难度适中,但是要在无交互的情况下一遍过应该还是比较困难,这里给出这些题目的思路和代码,仅供参考。
文章目录
概述
博主主要语言为Java,参加的是Java组的比赛,但是看起来各个研究生组别题目差别好像不大,这里主要是Java组的题,代码的语言也是Java。
代码在洛谷的提交情况:
1.试题 A: 数位倍数(5分填空)(easy)(模拟)
题目
【问题描述】
请问在 1 至 202504 (含)中,有多少个数的各个数位之和是 5 的整数倍。
例如:5 、19 、8025 都是这样的数。
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
思路
签到,简单模拟即可。
代码
public class Main {
static int dsum(int x) {
int sum = 0;
while(x > 0) {
int d = x % 10;
sum += d;
x /= 10;
}
return sum;
}
public static void main(String[] args) {
int ans = 0;
for(int i = 1; i <= 202504; i++) {
if(dsum(i) % 5 == 0) {
ans++;
}
}
// 40500
System.out.println(ans);;
}
}
2.试题 B: IPv6(5分填空)(hard)(dp)
这题作为一个编程题难度可能就有点大了,作为一个填空题,难度直接拉满,思路正确+一把写对+无法验证。我觉得完全可以加一些参数条件限制,作为一个压轴的编程题。
考场内做出的答案有点问题,考完后又改了几个bug,感觉答案应该是正确的,但是不敢完全确定。
链接直达:【2025蓝桥杯省赛填空压轴题-pythonA组和研究生组】Ipv6 解析(四维dp)
3.试题 C: 变换数组(10分编程)(easy)(模拟)
题目
【问题描述】
输入一个数组 a ,包含有 n 个元素 a1, a2, · · · , an 。对这个数组进行 m 次
变换,每次变换会将数组 a 中的每个元素 ai 转换为 ai
· bitCount(ai) 。其中
bitCount(x) 表示数字 x 的二进制表示中 1 出现的次数,例如 bitCount(3) = 2 ,
因为 3 的二进制表示为 11 ,其中 1 出现了两次。
请输出变换之后的数组内容。
【输入格式】
输入的第一行包含一个正整数 n ,表示数组 a 中的元素个数。
第二行包含 n 个整数 a1, a2, · · · , an ,相邻整数之间使用一个空格分隔。
第三行包含一个整数 m ,表示变换次数。
【输出格式】
输出一行,包含 n 个整数,相邻整数之间使用一个空格分隔,表示变换之
后得到的数组 a 。
【样例输入】
2
5 7
2
【样例输出】
20 63
【样例说明】
5 = (101)2 ,7 = (111)2 ,第一次变化后 a = [10, 21] 。
10 = (1010)2 ,21 = (10101)2 ,第二次变换后 a = [20, 63] 。
【评测用例规模与约定】
对于 30% 的评测用例,1 ≤ n ≤ 10 ;
对于 60% 的评测用例,1 ≤ n ≤ 100 ;
对于所有评测用例,1 ≤ n ≤ 103 ,0 ≤ m ≤ 5 ,0 ≤ ai ≤ 1000 。
思路
编程签到,简单模拟即可。数据范围很弱,不必担心TLE。如果数据范围很大的话,加一层map即可。
代码
import java.util.Scanner;
public class Main {
static void parr(int[] a) {
int n = a.length;
for(int i = 0; i < n; i++) {
System.out.print(a[i]);
if(i < n - 1) {
System.out.print(" ");
}
}
}
static int bit(int x) {
int sum = 0;
while(x > 0) {
if((x & 1) == 1) {
sum++;
}
x >>= 1;
}
return sum;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
for(int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int m = sc.nextInt();
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
a[j] = a[j] * bit(a[j]);
}
}
parr(a);
}
}
4.试题 D: 最大数字(10分编程)(easy)(二进制)
题目
【问题描述】
我们有 n 个连续的整数 1, 2, 3, · · · , n,可以自由排列它们的顺序。
然后,我们把这些数字转换成二进制表示,按照排列顺序拼接形成一个新
的二进制数。
我们的目标是让这个二进制数的值最大,并输出这个二进制对应的十进制
表示。
【输入格式】
输入一行包含一个正整数 n 。
【输出格式】
输出一行包含一个整数表示答案。
【样例输入】
3
【样例输出】
30
【样例说明】
1 的二进制为 1 ;2 的二进制为 10 ;3 的二进制为 11 ;其组成的最大的二
进制数字为 11110 ,对应的十进制数字为 30 。
【评测用例规模与约定】
对于 20% 的评测用例,1 ≤ n ≤ 10 ;
对于 40% 的评测用例,1 ≤ n ≤ 100 ;
对于 60% 的评测用例,1 ≤ n ≤ 500 ;
对于 80% 的评测用例,1 ≤ n ≤ 1000 ;
对于所有评测用例,1 ≤ n ≤ 10000 。
思路
其实就是一个排序问题。
对于两个整数 a a a 与 b b b,其拼接后得到的二进制串值为 a ∗ 2 ∣ b ∣ + b a*2^{|b|} +b a∗2∣b∣+b和 b ∗ 2 ∣ a ∣ + a b*2^{|a|}+a b∗2∣a∣+a。
写一个比较器进行排序再从大到小拼接即可。
代码
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int com(Integer x, Integer y) {
int b1 = blen(x), b2 = blen(y);
long l = x * (1 << b2) + y;
long r = y * (1 << b1) + x;
if(l > r) return -1;
if(l < r) return 1;
return Integer.compare(b2, b1);
}
static int blen(int num) {
return 32 - Integer.numberOfLeadingZeros(num);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Integer[] a = new Integer[n];
for(int i = 0; i < n; i++) {
a[i] = i + 1;
}
Arrays.sort(a, (x, y) -> com(x, y));
BigInteger ans = new BigInteger("0");
for(int i = 0; i < n; i++) {
ans = ans.shiftLeft(blen(a[i]));
ans = ans.add(BigInteger.valueOf(a[i]));
}
System.out.println(ans);
}
}
5.试题 E: 小说(15分编程)(easy-middle)(思维)
题目
【问题描述】
小蓝是一位网络小说家。现在他正在撰写一部新的推理小说,这部小说有
n 个不同的人物。
小说的每一章都有以下三种情节的一种:
1、A 发现 B 不知道真相。
2、A 发现 B 知道真相。
3、A 知道了真相。
为了保证读者的协调和新鲜感,小蓝的小说还要满足以下要求:
1、“ B 发现 A 不知道真相” 不能在 “ A 知道了真相” 后。
2、“ B 发现 A 知道真相” 不能在 “ A 知道了真相” 前。
3、“ B 发现 A 不知道真相” 不能在 “ B 发现 A 知道真相” 后。
4、相邻的两章情节类型不同,例如如果第一章是 A 发现 B 不知道真相那
么第二章就不能是 C 发现 D 不知道真相。
5、完全相同的情节不能出现两次。
现在小蓝希望知道,他最多能写多少章。
【输入格式】
输入的第一行包含一个正整数 n ,表示小说人数。
【输出格式】
输出一行包含一个整数表示答案,即小蓝最多能写多少章小说。
【样例输入 1】
2
【样例输出 1】
6
【样例说明 1】
以下是一种可能的情况:
1、B 发现 A 不知道真相。
2、A 知道了真相。
3、B 发现 A 知道真相。
4、A 发现 B 不知道真相。
5、B 知道了真相。
6、A 发现 B 知道真相。
小蓝一共能写 6 章。
【样例输入 2】
3
【样例输出 2】
13
【评测用例规模与约定】
对于 30% 的评测用例,n ≤ 5 ;
对于所有评测用例,1 ≤ n ≤ 10^9 。
思路
当小说中只有 1 1 1 个人时,唯一可写的情节只有“X 知道了真相”,故答案为 1 1 1 ;
当 n ≥ 2 n≥2 n≥2 时,小说中有三种情节,每种情节都与人物有关:
- 类型1: “A 发现 B 不知道真相”:要求 A 与 B 不同。对于每一对不同的 (A, B) 都可以构造一个这样的情节,共有 n ( n − 1 ) n(n-1) n(n−1)个。
- 类型2: “A 发现 B 知道真相”:同样每对 (A, B) (A ≠ B)可以构造一个,共有 n ( n − 1 ) n(n-1) n(n−1)个。
- 类型3: “A 知道了真相”:每个角色只能出现一次此情节,共有 n n n个。
如果没有其它限制,全局最多可以使用的不同情节总数是 n ( n − 1 ) + n ( n − 1 ) + n = 2 n 2 − n n(n-1) + n(n-1) + n = 2n^2 - n n(n−1)+n(n−1)+n=2n2−n。
题目除了顺序要求外,还有要求任意相邻的两章必须来自不同的情节类型。为了解决这个问题,必须“打散”连续的同类情节,也就是说,在全局的排列里必须“插入”其他类型的情节,将原本连续的类型1(或类型2)事件分离开来。每个角色事件内部较长的连续段必须借助其它角色的类型3事件“穿插”来断开,而这种“穿插”机制整体在全局排列中最多能够“补救”掉 2 n − 4 2n-4 2n−4 个位置。
因此,全局能达到的最大章节数为 2 n 2 − n − ( 2 n − 4 ) = 2 n 2 − 3 n + 4 2n^2 - n - (2n-4) = 2n^2 - 3n + 4 2n2−n−(2n−4)=2n2−3n+4
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
sc.close();
long ans;
if(n == 1) {
ans = 1;
} else {
// 当 n>=2 时,最大章节数为 2*n^2 - 3*n + 4
ans = 2 * n * n - 3 * n + 4;
}
System.out.println(ans);
}
}
6.试题 F: 01 串(15分编程)(middle)(二进制+模拟)
题目
【问题描述】
给定一个由 0, 1, 2, 3 · · · 的二进制表示拼接而成的长度无限的 01 串。其前
若干位形如 011011100101110111 · · · 。
请求出这个串的前 x 位里有多少个 1 。
【输入格式】
输入的第一行包含一个正整数 x 。
【输出格式】
输出一行包含一个整数表示答案。
【样例输入】
7
【样例输出】
5
【样例说明】
给定的串的前 7 位为 0110111 。
【评测用例规模与约定】
对于 60% 的评测用例,x ≤ 10^6 ;
对于所有评测用例,1 ≤ x ≤ 10^18 。
思路
暴力可以拿到60%的分数,如果不暴力该怎么做呢?
根据二进制位的原理,我们可以观察到:
- 对于 k ≥ 1 k ≥ 1 k≥1,数字 2 k – 1 2^{k–1} 2k–1 到 2 k – 1 2^k–1 2k–1 的二进制表示均为 k k k 位。
- 这一块总共有 2 k – 1 2^{k–1} 2k–1 个数字,整个块的总长度为 L ( k ) = k × 2 k – 1 L(k) = k × 2^{k–1} L(k)=k×2k–1。
- 而这块中,每个数字的最高位均为 1,再加上后面 k–1 位中各位出现1的次数固定可算出这一块的 1 的总数为 f ( k ) = 2 k – 1 + ( k – 1 ) × 2 k – 2 f(k) = 2^{k–1} + (k–1)×2^{k–2} f(k)=2k–1+(k–1)×2k–2.
据此,我们可以考虑对二进制位数进行分块,具体的流程为:
- 1.计算前x个位中能完全覆盖多少个块。
- 对于 k = 1 , 2 , … k = 1,2,… k=1,2,…依次累加 L ( k ) = k × 2 k – 1 L(k) = k×2^{k–1} L(k)=k×2k–1,直到如果再加下一块会超过 x x x。
- 此时,所有 k = 1 … m – 1 k = 1 … m–1 k=1…m–1 块均已完整放入前 x x x 位,而 m m m 位的那一块只取了部分内容。记录已经取了 a a a位。
- 2.统计这些块中1的数量。
- 依据上述 f ( k ) f(k) f(k)的计算公式计算这些块中1的数量。
- 3.处理最后一个可能不完整的块。
- 这一块包含 m m m 位的所有数字,数字从 2 m – 1 2^{m–1} 2m–1 开始,共 2 m – 1 2^{m–1} 2m–1 个。设 r = x – a r = x – a r=x–a 是余下的位数。第 m 块中每个数字占 m 位,设 f = f l o o r ( r / m ) f = floor(r / m) f=floor(r/m) 表示整数个数被完全取出;设 p a r t i a l = r m o d m partial = r \ mod \ m partial=r mod m 表示接下来数字取了部分位。
- 对于前 f f f 个数字,注意每个数字的二进制形式(定长 m 位)的最高位均为 1,其余 m – 1 m–1 m–1 位则是数字 i i i(从 0 0 0 到 f – 1 f–1 f–1)对应的(定长 m – 1 m–1 m–1 位)二进制表示;因此这部分贡献的1的个数为 f m a x − b i t + s u m i = 0 f – 1 c o u n t ( i ) f_{max-bit} + sum_{i=0}^{f–1} \ count(i) fmax−bit+sumi=0f–1 count(i).
- 对于第 f + 1 f+1 f+1个数字(即数字 2 m – 1 + f 2^{m–1} + f 2m–1+f)的前 p p p 位,我们直接用位运算提取这 p p p 位中 1 1 1 的个数(从最高位开始)。
代码
import java.util.Scanner;
public class Main {
static long getOneCount(long nbit) {
if(nbit == 1) {
return 1;
}
return (1L << (nbit - 1)) + (nbit - 1) * (1L << (nbit - 2));
}
static long getPcount(long f) {
if(f <= 0) {
return 0;
}
int max = 63 - Long.numberOfLeadingZeros(f);
long r = f - (1L << max);
return max * ((1L << max) >> 1) + r + 1 + getPcount(r);
}
static long getCount2(long f) {
return f + getPcount(f - 1);
}
static long getCount3(long p, long f, long nbit) {
long sum = 0;
long nnum = 1L << (nbit - 1);
nnum += f;
for(int i = (int)nbit - 1; i >= nbit - p; i--) {
if(((nnum >> i) & 1) == 1) {
sum++;
}
}
return sum;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long x = sc.nextLong();
if(x == 1) {
System.out.println(0);
return;
}
long acount = 1, ocount = 0, nbit = 0;
while(true) {
nbit++;
long blen = nbit * (1L << (nbit - 1));
if(acount + blen > x) {
break;
}
acount += blen;
ocount += getOneCount(nbit);
}
long r = x - acount;
long p = r % nbit, f = r / nbit;
long count2 = 0, count3 = 0;
if(f > 0) {
count2 = getCount2(f);
}
if(p > 0) {
count3 = getCount3(p, f, nbit);
}
System.out.println(ocount + count2 + count3);
}
}
7.试题 G: 甘蔗(20分编程)(middle)(dp)
题目
【问题描述】
小蓝种了一排甘蔗,甘蔗共 n 根,第 i 根甘蔗的高度为 ai 。小蓝想砍一些
甘蔗下来品尝,但是他有强迫症,不希望甘蔗的高度显得乱糟糟的。具体来说,
他给出了一个大小为 m 的整数集合 B = {b1, b2, · · · , bm} ,他希望在砍完甘蔗后,
任意两根相邻的甘蔗之间的高度差 |ai − ai+1| 都要在这个集合 B 中。小蓝想知道
他最少需要砍多少根甘蔗(对于高度为 h 的甘蔗,他可以将其砍成 x 高度的甘
蔗,x ∈ {0, 1, 2, · · · , h − 1} )。
【输入格式】
输入的第一行包含两个正整数 n, m ,用一个空格分隔。
第二行包含 n 个正整数 a1, a2, · · · , an ,相邻整数之间使用一个空格分隔。
第三行包含 m 个正整数 b1, b2, · · · , bm ,相邻整数之间使用一个空格分隔。
【输出格式】
输出一行包含一个整数表示答案。如果不能满足条件,输出 −1 。
【样例输入 1】
6 3
6 7 3 4 9 12
2 3 5
【样例输出 1】
2
【样例说明 1】
其中一种方案:将 a2 砍为 3 ,再将 a3 砍为 1 。
【样例输入 2】
2 1
4 5
6
【样例输出 2】
-1
【评测用例规模与约定】
对于 40% 的评测用例,1 ≤ n, m ≤ 8 ;
对于所有评测用例,1 ≤ n, m ≤ 500 ,1 ≤ ai ≤ 1000 ,0 ≤ bi ≤ 1000 。
思路
令 dp [ i ] [ x ] \text{dp}[i][x] dp[i][x] 表示前 i i i 根甘蔗,第 i i i 根被砍(或未砍)之后高度为 x x x 时,累计最小的砍的数量。目标是求 dp [ n ] [ x ] \text{dp}[n][x] dp[n][x] 的最小值( x x x 从 0 0 0 到 a [ n ] a[n] a[n] 中取得合法值)。
记第 i i i 根甘蔗砍完后的“最终高度”为 h ( i ) h(i) h(i)(满足 0 ≤ h ( i ) ≤ a [ i ] 0 ≤ h(i) ≤ a[i] 0≤h(i)≤a[i],其中若 h ( i ) = a [ i ] h(i) = a[i] h(i)=a[i] 则表示该甘蔗未被砍,否则表示已砍,代价记为 1 1 1)。
状态转移:
- 对于第
i
i
i 根甘蔗,我们要求存在一个
d
∈
B
d ∈ B
d∈B,使得
h
(
i
)
h(i)
h(i)与前一个甘蔗的高度
h
(
i
−
1
)
h(i-1)
h(i−1) 满足
h ( i − 1 ) − h ( i ) = ± d h(i-1) - h(i) = ± d h(i−1)−h(i)=±d,对于第 i 根甘蔗取值 x 时,只有当“前一根甘蔗的高度”为 x+d 或 x-d 且该状态存在时,转移才能成立。 - 代价的计算为:若当前甘蔗 i i i 取高度 x x x,若 x = a [ i ] x = a[i] x=a[i] 表示没砍,代价为 0 0 0;如果 x < a [ i ] x < a[i] x<a[i] 则表示砍过了,代价为 1 1 1。
最终,我们在 dp [ n − 1 ] \text{dp}[n-1] dp[n−1] 的所有状态中选择最小值作为答案。
代码
import java.util.Scanner;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int[] B = new int[m];
for (int i = 0; i < m; i++) {
B[i] = sc.nextInt();
}
// dp[i][x] 表示第 i 根甘蔗(0-indexed,第 0 根到第 n-1 根),最终高度为 x 时的最小砍甘蔗次数
final int INF = Integer.MAX_VALUE / 2;
// dp[0][x] 为第一根甘蔗的状态
int[] dpPrev = new int[1010];
Arrays.fill(dpPrev, INF);
for (int x = 0; x <= a[0]; x++) {
if(x == a[0]) {
dpPrev[x] = 0; // 不砍时代价 0
} else {
dpPrev[x] = 1; // 砍后代价 1
}
}
for (int i = 1; i < n; i++) {
int maxH = a[i];
int[] dpCur = new int[1010];
Arrays.fill(dpCur, INF);
for (int x = 0; x <= maxH; x++) {
int cost = (x == a[i] ? 0 : 1);
for (int d : B) {
// 情况1:上一根甘蔗高度 y = x + d
int y1 = x + d;
if (y1 < dpPrev.length) { // 注意 dpPrev 的数组长度为 a[i-1]+1
dpCur[x] = Math.min(dpCur[x], dpPrev[y1] + cost);
}
// 情况2:上一根甘蔗高度 y = x - d
int y2 = x - d;
if (y2 >= 0) {
dpCur[x] = Math.min(dpCur[x], dpPrev[y2] + cost);
}
}
}
dpPrev = dpCur;
}
// 最后答案为 dp[n-1][x] 中的最小值
int ans = INF;
for (int val : dpPrev) {
ans = Math.min(ans, val);
}
System.out.println(ans == INF ? -1 : ans);
}
}
8.试题 H: 原料采购(20分编程)(middle)(贪心)
题目
【问题描述】
小蓝负责一家工厂的原料采购。工厂有一辆运货卡车,其容量为 m 。工厂附近的采购点都在同一条路的同一方向上,一共有 n 个,每个采购点和工厂的距离各不相同。其中,第 i 个采购点的价格为 ai ,库存为 bi ,距离为
ci 。卡车每行驶一单位长度的路径就需要额外花费 o 。(返程没有花费,你也可以认为 o 实际是行驶两单位长度的花费)
请计算将卡车装满最少需要花费多少钱,如果没有任何方案可以装满请输出 −1 。
【输入格式】
输入的第一行包含三个正整数 n, m, o ,相邻整数之间使用一个空格分隔。接下来 n 行,每行包含三个正整数 ai
, bi, ci 表示一个采购点,相邻整数之间使用一个空格分隔。
【输出格式】
输出一行包含一个整数表示答案,即装满卡车所需的最小花费。
【样例输入】
3 5 1
99 9 1
3 4 99
1 2 190
【样例输出】
201
【评测用例规模与约定】
对于 40% 的评测用例,
n
≤
5000
,
m
≤
50000
n ≤ 5000 ,m ≤ 50000
n≤5000,m≤50000 ;
对于 60% 的评测用例,
m
≤
1
0
5
m ≤ 10^5
m≤105 ;
对于所有评测用例,
1
≤
n
≤
105
,
1
≤
m
,
o
≤
1
0
9
,
1
≤
a
i
,
b
i
,
c
i
≤
1
0
9
1 ≤ n ≤ 105 ,1 ≤ m, o ≤ 10^9 ,1 ≤ a_i, b_i, c_i ≤ 10^9
1≤n≤105,1≤m,o≤109,1≤ai,bi,ci≤109 ,保
证对于
i
>
1
i > 1
i>1 ,一定有
c
i
−
1
<
c
i
c_{i−1} < c_i
ci−1<ci 。
思路
遍历最远出发距离L,仅在所有距离不超过 L 的采购点中采购,总采购量必须 ≥ M;同时额外花费为 L×o(卡车从工厂到 L 处的路程费用)。在这些采购点中,为了使采购花费最低,贪心地先采购价格最低的,再采购价格较高的。
先按距离 c 升序排序所有采购点,然后依次将距离较近的点“加入”到一个基于价格(a)排序的TreeMap中,并维护该集合中总的库存;当累计库存大于等于 M 时,就从 TreeMap 中依照价格从低到高贪心“取” M 单位原料,计算采购花费,再加上当前候选 L(即当前采购点的距离)乘以 o 得到总花费。取所有可行情况中的最小值即为答案。
代码
import java.util.Scanner;
import java.util.*;
public class Main {
static int n, m, o;
static long[][] g;
static TreeMap<Long, Long> map;
static long mincost() {
long need = m, all = 0;
for(Map.Entry<Long, Long> entry : map.entrySet()) {
long a = entry.getKey();
long b = entry.getValue();
if(need <= b) {
all += need * a;
need = 0;
break;
} else {
all += a * b;
need -= b;
}
}
return need > 0 ? -1 : all;
}
static long solve() {
long all = 0, res = Long.MAX_VALUE;
int i = 0;
while(i < n) {
long c = g[i][2];
while(i < n && g[i][2] == c) {
long a = g[i][0], b = g[i][1];
map.put(a, map.getOrDefault(a, 0L) + b);
all += b;
i++;
}
if(all >= m) {
long min = mincost();
if(min < 0) {
continue;
}
res = Math.min(res, min + c * o);
}
}
return res == Long.MAX_VALUE ? -1 : res;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt(); m = sc.nextInt(); o = sc.nextInt();
g = new long[n][3];
map = new TreeMap<>();
for(int i = 0; i < n; i++) {
for(int j = 0; j < 3; j++) {
g[i][j] = sc.nextLong();
}
}
Arrays.sort(g, (a, b) -> (Long.compare(a[2], b[2])));
System.out.println(solve());
}
}
总结
填空压轴难度过大,编程题难度层次分明,整体做题体验不错。考察重点主要是二进制和dp。
ATFWUS 2025-04-14