1 条题解
-
0
题意分析
本题是一个缓冲区管理问题,核心需求是:在一组缓冲区中找到连续K个未锁定的缓冲区,使得它们的"价值和"最小。如果有多个符合条件的区间,选择起始位置最小的那个;如果不存在这样的区间,输出0。
具体要求:
- 缓冲区状态由字符表示:'0'-'9'表示占用或空闲(值为0表示空闲),'*'表示锁定
- 需要找到连续K个非锁定缓冲区(即不包含'*')
- 计算这些缓冲区的价值和('0'的价值为0,'1'-'9'按字面量计算)
- 若存在多个解,选择起始位置最小的
解题思路
核心问题转化
本质上是一个"滑动窗口"问题:在一个包含锁定标记的序列中,寻找长度为K的合法窗口(无'*'),并计算窗口内的价值和最小值。
算法选择
- 滑动窗口算法:适用于在数组/序列中寻找固定长度的最优子区间
- 前缀和优化:在窗口滑动时,通过"去头加尾"快速更新窗口和,避免重复计算
关键步骤
- 输入处理:读取缓冲区状态,过滤掉换行符
- 窗口初始化:从左到右遍历,维护一个当前有效窗口
- 窗口滑动:
- 遇到'*'时,重置窗口状态(长度和当前和)
- 否则,扩展窗口长度并累加价值
- 当窗口长度达到K时,计算当前和并更新最小值
- 窗口长度超过K时,减去左侧元素的价值(滑动窗口)
- 结果判断:若未找到合法窗口,输出0;否则输出最优窗口的起始位置
标程
#include <iostream> #include <cstdio> #include <string> #include <algorithm> using namespace std; char s[100010]; // 存储缓冲区状态 int main() { int n, k; scanf("%d%d", &n, &k); // 读取缓冲区数量和目标长度 if (n < k) { // 缓冲区数量不足,直接输出0 cout << 0 << endl; return 0; } int currentLength = 0; // 当前窗口长度 int currentSum = 0; // 当前窗口价值和 int minSum = 0x7fffffff; // 最小价值和(初始化为极大值) int minPos = 0; // 最小价值和对应的起始位置 for (int i = 1; i <= n; i++) { char ch; scanf("%c", &ch); // 读取单个字符 if (ch == '\n') { // 跳过换行符 i--; continue; } s[i] = ch; if (ch == '*') { // 遇到锁定标记,重置窗口 currentLength = 0; currentSum = 0; } else { currentLength++; int value = ch - '0'; // 转换为数值 if (currentLength > k) { // 窗口超过目标长度,滑动窗口 currentSum = currentSum - (s[i - k] - '0') + value; // 更新最小值 if (currentSum < minSum) { minSum = currentSum; minPos = i - k + 1; } } else if (currentLength == k) { // 窗口刚好达到目标长度 currentSum += value; if (currentSum < minSum) { minSum = currentSum; minPos = i - k + 1; } } else { // 窗口尚未达到目标长度,继续累加 currentSum += value; } } } // 输出结果:若未找到合法窗口,输出0;否则输出最小起始位置 cout << (minSum == 0x7fffffff ? 0 : minPos) << endl; return 0; }
算法复杂度分析
- 时间复杂度:O(N),其中N为缓冲区数量。每个字符仅遍历一次,滑动窗口操作均为常数时间。
- 空间复杂度:O(N),用于存储缓冲区状态数组。
关键逻辑说明
- 锁定标记处理:遇到'*'时立即重置窗口,确保窗口内不包含锁定缓冲区。
- 窗口滑动优化:当窗口长度超过K时,通过"减去左侧元素值+加上右侧元素值"更新窗口和,避免重新计算整个窗口。
- 起始位置计算:窗口起始位置为
i - k + 1
,其中i为当前处理的字符位置。 - 边界条件处理:
- 若N < K,直接输出0(缓冲区数量不足)
- 若全程未找到合法窗口,minSum保持初始极大值,最终输出0
- 1
信息
- ID
- 755
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者