题解:洛谷 P3056 Clumsy Cows

【题目来源】

洛谷:P3056 [USACO12NOV] Clumsy Cows S - 洛谷

【题目描述】

奶牛 Bessie 正试图在她的新笔记本电脑上输入一个平衡的括号字符串,但由于她的蹄子很大(因此非常笨拙),她不断地输入错误的字符。请通过计算要使该字符串变为平衡,最少需要反转多少个字符(例如,将左括号变为右括号,或反之)来帮助她。

对于“括号字符串平衡”有几种定义方法。或许最简单的定义是,字符串中的 () 总数必须相同,并且对于字符串的任何前缀,( 的数量必须不少于 ) 的数量。例如,以下字符串都是平衡的:

()

(())

()(()())

而以下则不平衡:

)(

())(

((())))

【输入】

一个只包含()的字符串,长度为偶数,最多 \(100000\) 个字符。

【输出】

一个整数,表示要将该字符串变为平衡字符串,最少需要反转的括号数量。

【输入样例】

())(

【输出样例】

2

【核心思想】

  1. 问题分析:给定一个由 () 组成的字符串,求最少反转多少个括号使其变为平衡字符串。平衡的定义:左右括号数量相等,且任意前缀中 ( 的数量不少于 ) 的数量。这是一个栈模拟/贪心问题,关键在于用栈处理匹配,统计不匹配的括号数量。

  2. 算法选择

    • 栈模拟匹配:遍历字符串,遇到 ( 入栈,遇到 ) 尝试出栈。若栈空时遇到 ),说明需要反转(num1++),并将反转后的 ( 入栈
    • 剩余左括号处理:遍历结束后栈中剩余的 ( 需要一半改为 )num2/2
  3. 关键步骤

    • 读取输入:字符串 \(S\)
    • 栈处理(遍历每个字符):
      • 若为 (:入栈
      • 若为 )
        • 若栈空:\(num1 \mathrel{+}= 1\)(需要反转),将 ( 入栈(模拟反转)
        • 否则:出栈(匹配成功)
    • 统计剩余:栈中剩余左括号数 = \(num2\),需要 \(num2/2\) 次反转
    • 输出 \(num1 + num2/2\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(|S|)\)
    • 空间复杂度:\(O(|S|)\),栈空间
  5. 栈匹配的核心思想

    • 贪心匹配:遇到 ) 时优先与栈顶 ( 匹配,无法匹配则立即反转(贪心策略保证最优)
    • 反转代价统一:栈空时遇到 ) 反转代价为 \(1\),后续可与后面的 ) 匹配;剩余 ( 两两配对,每对需反转一个
    • 平衡条件转化:最终栈中剩余 \(num2\)(,说明有 \(num2\)( 多余,由于总数平衡,必有 \(num2\)) 也多余(已计入 \(num1\)),每对需一次反转
    • 适用于"括号匹配 + 最小修改"类问题,核心是用栈模拟并统计不匹配情况

【解题思路】

【算法标签】

普及- #栈

【代码详解】

#include <bits/stdc++.h>
using namespace std;
string s;
int num1, num2;
int main()
{
    cin >> s;  // 输入字符串s
    stack<char> st;  // 定义队列
    for (int i=0; i<s.length(); i++) {  // 遍历所有字符
        if (s[i]=='(') {  // 如果是左括号
            st.push('(');  // 就压入栈中
        } else {  // 如果是右括号
            if (st.empty()) {  // 如果栈为空
                num1++;  // 则调整计数器自增1
                st.push('(');  // 修改为左括号后压入栈
            } else {  // 如果不为空
                st.pop();  // 则弹出栈顶的左括号
            }
        }
    }
    while (!st.empty()) {  // 当栈不为空
        st.pop();  // 统计栈中有多少左括号
        num2++;
    }
    cout << num2/2+num1 << endl;  // 栈中左括号中有一半需要修改为右括号,再加上之前统计的值
    return 0;
}

【运行结果】

())(
2
posted @ 2026-08-28 15:57  团爸讲算法  阅读(3)  评论(0)    收藏  举报