1478 括号序列的最长合法子段
Posted happy_code
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1478 括号序列的最长合法子段相关的知识,希望对你有一定的参考价值。
这里有另一个关于处理合法的括号序列的问题。
如果插入“+”和“1”到一个括号序列,我们能得到一个正确的数学表达式,我们就认为这个括号序列是合法的。例如,序列"(())()", "()"和"(()(()))"是合法的,但是")(", "(()"和"(()))("是不合法的。
这里有一个只包含“(”和“)”的字符串,你需要去找到最长的合法括号子段,同时你要找到拥有最长长度的子段串的个数。
Input
第一行是一个只包含“(”和“)”的非空的字符串。它的长度不超过 1000000。
Output
输出合格的括号序列的最长子串的长度和最长子串的个数。如果没有这样的子串,只需要输出一行“0 1”。
Input示例
)((())))(()())
Output示例
6 2
//括号匹配,将 ( 做 1 , ) 为 -1 ,就可以得到一串数字,求出前缀和,那么,前缀和相同,并且,又端点的值是区间中最小的,即为合法序列,用单调栈维护一个上升前缀和即可。
1 # include <bits/stdc++.h> 2 using namespace std; 3 # define LL long long 4 # define INF 0x3f3f3f3f 5 # define MX 100005 6 /**************************/ 7 # define BUF_SIZE 1000005 8 # define OUT_SIZE 1000005 9 bool IOerror=0; 10 11 inline char nc(){ 12 static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; 13 if (p1==pend){ 14 p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); 15 if (pend==p1){IOerror=1;return -1;} 16 //{printf("IO error!\n");system("pause");for (;;);exit(0);} 17 } 18 return *p1++; 19 } 20 inline bool blank(char ch){return ch==‘ ‘||ch==‘\n‘||ch==‘\r‘||ch==‘\t‘;} 21 inline void read(int &x){ 22 bool sign=0; char ch=nc(); x=0; 23 for (;blank(ch);ch=nc()); 24 if (IOerror)return; 25 if (ch==‘-‘)sign=1,ch=nc(); 26 for (;ch>=‘0‘&&ch<=‘9‘;ch=nc())x=x*10+ch-‘0‘; 27 if (sign)x=-x; 28 } 29 inline void read(char *s){ 30 char ch=nc(); 31 for (;blank(ch);ch=nc()); 32 if (IOerror)return; 33 for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch; 34 *s=0; 35 } 36 37 const int N=1000005; 38 struct Node{ 39 int dex; 40 int num; 41 }; 42 char str[N]; 43 int sum[N]; 44 int ans[N]; 45 46 int main () 47 { 48 read(str+1); 49 int len = strlen(str+1); 50 for (int i=1;i<=len;++i) 51 { 52 sum[i] = sum[i-1] + (str[i]==‘(‘?1:-1); 53 } 54 stack<Node> st; 55 st.push((Node){0,0}); 56 ans[0]=1; 57 for (int i=1;i<=len;++i) 58 { 59 while (!st.empty()&&sum[i]<st.top().num) st.pop(); 60 if (!st.empty()&&sum[i]==st.top().num) 61 { 62 Node tp=st.top(); st.pop(); 63 while (!st.empty()&&sum[i]==st.top().num) 64 { 65 tp = st.top(); st.pop(); 66 } 67 int ch = i-tp.dex; 68 ans[ch]++; 69 st.push(tp); 70 } 71 else st.push((Node){i,sum[i]}); 72 } 73 int mdex=0; 74 for (int i=1;i<=len;++i) 75 if (ans[i]) mdex=i; 76 printf("%d %d\n",mdex,ans[mdex]); 77 return 0; 78 }
以上是关于1478 括号序列的最长合法子段的主要内容,如果未能解决你的问题,请参考以下文章
LongestValidParentheses, 求最长合法括号子串长度-----同类问题ValidParentheses,GenerateParentheses
2023-03-02:给定一个数组arr,长度为n, 任意相邻的两个数里面至少要有一个被选出来,组成子序列,才是合法的! 求所有可能的合法子序列中,最大中位数是多少? 中位数的定义为上中位数, [1,