括号序列

题目描述

一个由小括号组成的字符串可以被称为一个括号序列。但一个括号序列可能并不满足括号匹配的要求。因此,我们可以进一步将满足括号匹配的括号序列成为“标准的括号序列。例如字符串")((())"是一个括号序列但不是标准的括号序列,而字符串"()(())"是一个标准的括号序列。
给定一个括号序列,你需要对求出:这个括号序列的所有不同的子串中,有多少个是标准的括号序列?
一个括号序列的子串指的是这个序列从某个位置起始、到某个位置截止的子字符串。如果两个子串拥有不同的起始位置或截止位置,那么它们就被认为是括号序列的不同的子串。
 

 

输入

包括一行一个字符串,为给定的括号序列。

 

输出

输出一个整数,为标准的括号序列的子串的个数。

 

样例输入

()(())

样例输出

4

 

提示

设输入字符串的长度为n。
对于30%的数据,满足n≤200。
对于60%的数据,满足n≤5000。
对于100%的数据,满足1≤n≤10^6。

题解:题目要求必须是子串,也就是要连续的,因此当前面有一个合法的话,如果紧接着又出现了一个合法的,那么方法数就是(1+1)种,如果前面有n种连续的合法的括号的话,紧接着又出现一个合法的,那么方法数就是(1+n),所以每当遇到一个合法的括号对的时候,看他前面是否有连续的括号对,用stack记录,用stack.pre来记录当以这个括号作为两个连续合法序列的分隔时,这个括号后面有多少个合法的序列。

 

复制代码
#include <bits/stdc++.h>
#define ll long long
#define met(a,x) memset(a,x,sizeof(a))
#define inf 0x3f3f3f3f
using namespace std;
const int N=1e6+10;
const int mod=1e9+7;
char a[N];
struct node
{
    int x,pre;
} b;
stack<node> s;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>a+1;
    int len=strlen(a+1);
    ll ans=0;
    ll sum=0;
    for(int i=1; i<=len; i++)
    {
        if(a[i]=='(')
            b.x=1;
        else
            b.x=2;
        if(!s.empty())
        {
            if(s.top().x==1&&b.x==2)
            {
                s.pop();
                if(s.empty())
                {
                    ans+=(sum+1);
                    sum++;
                }
                else
                {
                    ans+=(s.top().pre+1);
                    s.top().pre++;
                }
            }
            else
                s.push(b);
        }
        else
            s.push(b);
    }
    cout<<ans<<endl;
    return 0;
}
复制代码

 

posted @   oc_co  阅读(854)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示