一、问题重述
我们需要从n名按入狱时间排序的罪犯中,找出所有长度为c的连续子序列,使得这些子序列的罪行值之和不超过t。这是一个典型的滑动窗口问题,适合用高效算法解决。
二、C++代码实现
#include <iostream>#include <vector>using namespACe std;int main() { int n, t, c; while (cin >> n >> t >> c) { // 处理多组测试数据 vector<int> crimes(n); for (int i = 0; i < n; ++i) { cin >> crimes[i]; // 读取每个罪犯的罪行值 } int count = 0; // 记录符合条件的窗口数量 long long window_sum = 0; // 当前窗口的和,使用long long防止溢出 // 初始化第一个窗口 for (int i = 0; i < c; ++i) { window_sum += crimes[i]; } if (window_sum <= t) { count++; } // 滑动窗口:每次移动一位 for (int i = c; i < n; ++i) { // 减去离开窗口的元素,加上新进入窗口的元素 window_sum = window_sum - crimes[i - c] + crimes[i]; if (window_sum <= t) { count++; } } cout << count << endl; } return 0;}// 64 位输出请用 printf("%lld")
三、算法核心思想
滑动窗口算法通过维护一个固定大小的"窗口"(这里是c名罪犯),在遍历数组时高效更新窗口内的信息。相比暴力解法(O(n²)时间复杂度),滑动窗口将复杂度降低到O(n)。
四、关键步骤解析
初始化窗口:计算前c个元素的和作为初始窗口
滑动过程:
窗口右移一位
减去最左边离开窗口的元素值
加上新进入窗口的右边元素值
条件检查:每次更新窗口后检查总和是否≤t
五、算法优化空间
提前终止:如果发现某个窗口和>t,可以跳过后续检查
并行计算:对于超大n,可分块并行处理
预处理:构建前缀和数组可支持多种查询
来源:竞赛学习
點擊查看更多內(nèi)容
為 TA 點贊
評論
評論
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章
正在加載中
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦