上海计算机学会2026年4月月赛C++丙组T2 括号消除
·
括号消除
题目描述
给定一个只含 ( 与 ) 的字符串 SSS,定义消除操作如下:
从 SSS 的第一个字符开始,检查是否出现 (),如果存在,则从 SSS 中删除第一个出现的 (),然后开始新一轮的消除操作。
若对 SSS 进行上述消除操作,直到 SSS 再也找不到任何 () 为止。请输出停止操作时,SSS 还剩多少个字符。
输入格式
单个字符串表示输入的括号序列。
输出格式
单个整数表示答案。
数据范围
记 ∣S∣|S|∣S∣ 表示输入字符的长度,则:
- 30% 的数据:1≤∣S∣≤1001 \le |S| \le 1001≤∣S∣≤100
- 100% 的数据:1≤∣S∣≤3000001 \le |S| \le 3000001≤∣S∣≤300000
样例数据
输入1:
((())
输出1:
1
输入2:
)(
输出2:
2
题解
我来给大家讲解这道括号消除题的解题思路和代码实现~
解题思路
这道题的核心是模拟合法括号对的消除过程,但直接模拟字符串删除会超时(尤其数据量达到3e5时),所以我们用计数法高效解决:
- 用变量
z记录未匹配的左括号(数量 - 用变量
cnt记录无法匹配的右括号)数量 - 遍历字符串:
- 遇到左括号,直接累加未匹配左括号数
- 遇到右括号:如果有未匹配的左括号,就配对消除(左括号数-1);否则这个右括号无法匹配,记录下来
- 最终剩余字符数 = 未匹配的左括号数 + 无法匹配的右括号数
这个方法时间复杂度 O(n)O(n)O(n),空间复杂度 O(1)O(1)O(1),完美适配大数据范围。
带注释代码(仅添加注释,不修改代码)
// 引入C++所有标准库头文件
#include <bits/stdc++.h>
using namespace std;
int main(){
char c; // 存储当前读取的字符
int cnt = 0; // 记录无法匹配的右括号 ) 的数量
int z = 0; // 记录未匹配的左括号 ( 的数量
// 循环读取字符串中的每一个字符
while(cin >> c){
if (c == '('){
z++; // 遇到左括号,未匹配左括号数+1
}else{
if (z > 0){
z--; // 有可匹配的左括号,配对消除,左括号数-1
}else{
cnt++; // 无可用左括号,该右括号无法匹配,计数+1
}
}
}
// 最终剩余字符 = 未匹配左括号 + 无法匹配右括号
cout << z + cnt;
return 0;
}
代码解释
- 变量定义:
c:逐个读取输入的括号字符z:统计当前还没配对的左括号数量cnt:统计没有左括号可以配对的右括号数量
- 遍历逻辑:
- 左括号:直接暂存,等待后续右括号配对
- 右括号:优先和前面的左括号配对,无左括号可配则标记为剩余字符
- 结果计算:配对完成后,剩下的左括号和无法配对的右括号就是最终剩余的字符。
总结
- 核心思路:用计数替代字符串删除,高效处理大数据量
- 两个变量分工:
z存未匹配左括号,cnt存无法匹配右括号 - 最终答案:
z + cnt,时间复杂度线性,空间常数级
更多推荐
所有评论(0)