CodeForces ~ 1000B ~ Light It Up(思维)

探讨了如何通过一次额外的开关操作使灯保持点亮状态的时间最长。分析了操作对开关序列的影响,并提供了一段C++代码实现。

题意

有一盏灯,0时刻开着。n次操作,你可以在其中加入一次操作(或者不加),操作为:a[i]时刻按一下开关,状态变为相反状态(开->关or关->开)。问灯亮着的时长最长为多少?
保证a[i-1]<a[i]。
3 10
4 5 7
0~4开(时长为4-0),4~6关(时长为6-4),6~7开(时长为7-5),7~10关(时长为10-7)
我们可以在第3个时刻操作一下开关,过程变为:0~3开(时长为3-0),3~4关(时长为4-0),4~6开(时长为6-4),5~7关(时长为7-5),7~10开(时长为10-7),3+2+3=8


题解

比如第一个样例:开关灯时长为:4(开) 1(关) 2(开) 3(关) ,我们加一次操作相当于把某个数字拆成两个,肯定为一开一关,我们肯定让开最大(即该数字-1),拆完之后的开灯时长为:该数字之前的总开灯时长+该数字之后的总关灯时长+该数字-1。
记录到第i次操作时亮灯时长记为b[i]。每次操作后开灯时长为:b[i]+m-a[i]-(b[n+1]-b[i])-1,所以遍历一遍维护最大值即可。别忘了可以不操作,此时开灯时长为b[n+1]。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5+5;
int n, m, a[MAXN], b[MAXN];
int main()
{
    scanf("%d%d", &n, &m);
    int f = 1;//开关
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        b[i] += b[i-1]+f*(a[i]-a[i-1]);
        f ^= 1;//0->1 or 1->0
    }
    b[n+1] = b[n]+f*(m-a[n]);
    int ans = b[n+1];//不加操作的开灯时长
    for (int i = 1; i <= n; i++)
        ans = max(ans, b[i]+m-a[i]-(b[n+1]-b[i])-1);
    printf("%d\n", ans);
    return 0;
}
/*
3 10
4 6 7
*/
### Codeforces 思维题解题思路和技巧 #### 预处理的重要性 对于许多竞赛编程问题而言,预处理能够显著提高效率并简化后续操作。通过提前计算某些固定的数据结构或模式匹配表,可以在实际求解过程中节省大量时间。例如,在字符串处理类题目中预先构建哈希表来加速查找过程[^1]。 #### 算法优化策略 针对特定类型的输入数据设计高效的解决方案至关重要。当面对大规模测试案例时,简单的暴力破解往往无法满足时限要求;此时则需考虑更高级别的算法改进措施,比如动态规划、贪心算法或是图论中的最短路径算法等。此外,合理利用空间换取时间也是一种常见的优化手段[^2]。 #### STL库的应用价值 C++标准模板库提供了丰富的容器类型(vector, deque)、关联式容器(set,map)以及各种迭代器支持,极大地便利了程序开发工作。熟练掌握这些工具不仅有助于快速实现功能模块,还能有效减少代码量从而降低出错几率。特别是在涉及频繁插入删除场景下,优先选用双向队列deque而非单向链表list可获得更好的性能表现。 ```cpp #include <iostream> #include <deque> using namespace std; int main(){ deque<int> dq; // 向两端添加元素 dq.push_back(5); dq.push_front(3); cout << "Front element is: " << dq.front() << endl; cout << "Back element is : " << dq.back() << endl; return 0; } ``` #### 实际应用实例分析 以一道具体题目为例:给定一系列查询指令,分别表示往左端/右端插入数值或者是询问某个指定位置到边界之间的最小距离。此题目的关键在于如何高效地追踪最新状态而无需重复更新整个数组。采用双指针技术配合静态分配的一维数组即可轻松解决上述需求,同时保证O(n)级别的总运行成本[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值