PTA 3 括号匹配调整

如果通过插入“ +”和“ 1”可以从中得到格式正确的数学表达式,则将带括号的序列称为正确的。

例如,序列 "(())()","()"和 "(()(()))"是正确的,而")(","(()))("和"(()" 不是。

定义重新排序操作:选择括号序列的任意连续子段(子字符串),然后以任意方式对其中的所有字符进行重新排序。

当重新排序的子段的长度为t时,重新排序操作需要耗时t秒。

例如,对于“))((”,他可以选择子字符串“)(”并重新排序“)()(”(此操作将花费2秒)。

不难看出,重新排序操作不会改变左括号和右括号的数量。

现在,LD想花费最少的时间,通过任意次数(可能为零)执行重新排序操作来使括号序列变成正确的。

输入格式:

第一行包含一个整数n(1≤n≤1e6),表示序列的长度;

第二行包含一个长度为n的字符串,仅由字符‘(’和‘)’组成。

输出格式:

输出一个整数,表示使括号序列正确的最小秒数;如果不可能实现,则输出-1。

输入样例:

8
))((())(

输出样例: 

6

代码:

#include<stdio.h>
int main()
{
    int num;    scanf("%d", &num);
    char stack[num + 1] = {'0'}; int top = 1, ans = 0;  // 栈首元素来一个'0',防止越界读取
    char str[num + 1];  scanf("%s", str);

    for (int i = 0; i < num; i++)
    {
        // 读取到 '('
        if (str[i] == '(')
        {
            // 若栈顶是 ')',即 将会形成 )(,出现一组不匹配的
            if (stack[top-1] == ')')
            {
                // 交换两个,次数+2
                ans += 2;
                top--;  // 把 ')' 从栈顶退出.
            }
            // 如果不是 ,就把他存入栈里
            else stack[top++] = '(';
        }
        // 读取到 ')'
        else
        {
            // 若栈顶是'(',能匹配,退栈.
            if (stack[top-1] == '(') top--;
            // 否则把')'入栈
            else stack[top++] = ')';
        }
    }
    // 如果还有括号没匹配在栈里,那么这个是不可能调整为合法的
    if (top != 1) printf("-1");
    else printf("%d", ans);
    return 0;
}

总结:

        这道题的合法非法说人话就是括号能不能匹配,那么又是一道栈的题目了.

        那么怎么才算花费最少步数呢?如果想要重新调整成合法的话,那么至少每一个有问题的括号都得重新排序一次,因为每次重新排序都是针对两个字符,所以每排序一次都进行了两步.因此我们每遇到一组不匹配的我们便让答案+=2即可.

        那么什么情况会无法转变为合法呢?显然当左右括号个数不相等时,绝对会出现无法匹配的括号.遇到此情况我们输出-1即可.反映到栈里,就是当结束循环后栈里仍有数据.

        因此利用栈我们可以很快的解决问题.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值