Hello World 2025 蓝桥杯选拔赛题解
T552570 小 hi 的奇妙旅行 Ⅰ
注意数据范围:int 类型数据最大能存约 long long 类型
AC 代码示例
T552044 小 hi 的奇妙旅行 Ⅱ
一个
N 行M 列的字符串矩阵中,本来有一个全由#字符构成的矩形,但矩形缺了一个口子用.字符代替,找到这个缺口的坐标。
- 第一次遍历矩阵,找出所有
#字符的最小行min_x 、最大行max_x 、最小列min_y 、最大列max_y ,就能得到#字矩形的完整形状 - 第二次遍历
min_x,max_x,min_y,max_y 范围找到唯一的.字符坐标就是答案
AC 代码示例
T550776 小 hi 的奇妙旅行 Ⅲ
- 策略是先加所有负数,取一次绝对值,再加上所有正数(或者先正数再负数),最终的绝对值就是最大值
- 代码实现可以把所有数字的绝对值相加
- 注意数据范围要用
long long
AC 代码示例
点击链接查看数据生成代码
T550777 小 hi 的奇妙旅行 Ⅳ
60% 数据做法
- 从
1 到n 依次枚举在加到第i 个数字时进行一次取反操作的话,最终结果的绝对值,取所有枚举结果中的最大值,就是答案 - 时间复杂度
O(n^2)
参考代码
满分做法
- 预处理前缀和
sum_i=\sum_{j=1}^i num_j 优化暴力做法 - 枚举到第
i 个数字时,直接对当前结果取反(即-sum_i )加上后面n-i 个数字的和(即sum_n-sum_i ),这样只需要O(n) 次枚举,每次枚举O(1) 计算得到结果,对所有枚举结果取最大绝对值 - 整体时间复杂度
O(n)
AC 代码示例
点击链接查看数据生成代码
T551846 小 hi 的奇妙旅行 Ⅴ
60% 数据做法
- 从
1 到n 依次枚举在加到第i 个数字时进行一次取反操作的情况,对每次加完后的结果都取一次绝对值的最大值就是答案 - 时间复杂度
O(n^2)
参考代码
满分做法
- 假设在第
i 个数字进行取反,求后n-i 个数字在计算过程中可能出现的最大绝对值 - 如果可以维护计算时出现的最大值与最小值,就可以对每次枚举
O(1) 算出后续计算过程中绝对值的最大值 - 如果只取出后
n-i 个数字单独组成一个数组,这些数字计算过程的最大(最小)值也就是从第i+1 个数字往后加的过程中,相对前i 个数字和的最大、最小偏移量,满足如下公式:
同理
- 以上
mx_{i+1} 与mn_{i+1} 排除了前i 个数字对后面计算的影响,将前i 个数字的“和的相反数”考虑进去后,就是最终在整个计算过程中的最大、最小值:
AC 代码示例
点击链接查看数据生成代码
T552288 小 hi 的奇妙旅行 Ⅵ
- 若
n\geq m :取n 个数字的前m 个反复依次加到第1 到第m 个位置上,加满L 轮,问最后哪个位置的数字最大;- 若
n<m :将n 个数字依次加到m 个位置上,如果n 个数字用完了再从第1 个数字开始循环往后加,直到加满L 轮。
60% 数据做法
-
- 时间复杂度
O(nL) - 若考虑当
n\geq m 时,最终大小只取决于前m 个数字的大小,与L 无关,能通过66\% 的数据
参考代码
满分做法
- 若
n\geq m ,则只需要考虑前m 个数字的大小,本题难点在n<m 的情况 - 为方便说明,这里以
n=6,m=8,L=5 的情况为例,以下表格中,第i 行表示第i 个位置(人),第j 列表示第i 个位置被第j 次被累加(均从0 开始)
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | ||||
| 1 | ||||
| 2 | ||||
| 3 | ||||
| 4 | ||||
| 5 | ||||
| 6 | ||||
| 7 |
- 首先观察到,第
0 个位置依次被h_0,h_2,h_4 累加,第2 个位置依次被h_2,h_4,h_0 累加,第4 个位置依次被h_4,h_0,h_2 累加,如果L 足够大,这将是一个在行上以2 为周期、在列上以3 为周期的循环,行周期T_{row}=\gcd(n,m) ,列周期T_{col}=\frac{lcm(n,m)}{m}=\frac{nm}{\gcd(n,m)\times m}=\frac{n}{\gcd(n,m)} - 首先以行为周期考虑
- 每
T_{row}=\gcd(n,m) 行为一个周期,因此只需要处理前i=0,1,\cdots,T_{row}-1 行,就可以O(1) 推出后面的i+T_{row},i+2T_{row},...,i+kT_{row} 行 - 第
0,2,4 行对应的h_i 下标集合均为0,2,4 循环,且下标的顺序不变,因此对于第i~(0\leq i<T_{row}) 行,处理出该行的前缀和,后续第i+kT 行就可以用利用该前缀和循环性质O(1) 计算出结果
- 每
- 再以每行内的列为周期考虑
- 首先计算出经过
L 轮后,第i 行有\frac{nL}{m}+((nL\%m)>i?1:0) 列,其中\frac{nL}{m} 表示L 轮经过了完整的列数,最后的(nL\%m)>i 表示在nL 无法整除m 的情况下是否多出一列,若多出一列,则列数加一 - 先处理出前
T_{col}=\frac{n}{\gcd(n,m)} 列的前缀和sum_i=\sum_j^i h_j~i ,列数在T_{col} 整数倍的部分可以直接用sum_{T_{col}} 的整数倍乘上去,多出来的部分使用循环下标的前缀和计算
- 首先计算出经过
AC 代码示例
点击链接查看数据生成代码