Educational Codeforces Round 45 (Rated for Div. 2)
A regular bracket sequence is a bracket sequence that can be transformed into a correct arithmetic expression by inserting characters "1" and "+" between the original characters of the sequence. For example, bracket sequences "()()", "(())" are regular (the resulting expressions are: "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.
You are given nn bracket sequences s1,s2,…,sns1,s2,…,sn . Calculate the number of pairs i,j(1≤i,j≤n)i,j(1≤i,j≤n) such that the bracket sequence si+sjsi+sj is a regular bracket sequence. Operation ++ means concatenation i.e. "()(" + ")()" = "()()()".
If si+sjsi+sj and sj+sisj+si are regular bracket sequences and i≠ji≠j , then both pairs (i,j)(i,j) and (j,i)(j,i) must be counted in the answer. Also, if si+sisi+si is a regular bracket sequence, the pair (i,i)(i,i) must be counted in the answer.
The first line contains one integer n(1≤n≤3⋅105)n(1≤n≤3⋅105) — the number of bracket sequences. The following nn lines contain bracket sequences — non-empty strings consisting only of characters "(" and ")". The sum of lengths of all bracket sequences does not exceed 3⋅1053⋅105 .
In the single line print a single integer — the number of pairs i,j(1≤i,j≤n)i,j(1≤i,j≤n) such that the bracket sequence si+sjsi+sj is a regular bracket sequence.
3
)
()
(
2
2
()
()
4
In the first example, suitable pairs are (3,1)(3,1) and (2,2)(2,2) .
In the second example, any pair is suitable, namely (1,1),(1,2),(2,1),(2,2)(1,1),(1,2),(2,1),(2,2) .
题意:有n个字符串,每个字符串都只有'('和')'组成,从中找出两个字符串可以构成完全匹配的个数(这两个字符串也可以由自己本身组成,如(2,2),(1,1).
题解:所有的字符串可以分为3类:1.自身完美匹配型(即左括号和右括号完美匹配)2:除去完全匹配的子串,剩下的都是左括号,3:除去完全匹配的子串,剩下的都是右括号。对于第一类他的个数ans=c(n,2)*A(2,2)+n(它自身构成的完美匹配),对于第二类和第3类,用map查询一遍(如果有左括号的个数等于右括号的个数,ans=(左括号的种类*右括号的种类),最后不要忘记除去2,因为我们算了两遍。还有一点要注意的是一定要用long long ,我错了好几次才发现这一点。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stack> 4 #include<string.h> 5 #include<queue> 6 #include<algorithm> 7 #include<iostream> 8 #include<map> 9 #include<vector> 10 #define PI acos(-1.0) 11 using namespace std; 12 typedef long long ll; 13 const int MAXN=3e5+10; 14 ll m; 15 ll ans; 16 char str[MAXN]; 17 map<ll ,ll>::iterator it; 18 int main() 19 { 20 ll T; 21 scanf("%lld",&T); 22 map<ll,ll>mp; 23 mp.size(); 24 while(T--) 25 { 26 stack<char>s; 27 scanf(" %s",&str); 28 ll len=strlen(str); 29 for(ll i=0;i<len;i++) 30 { 31 if(!s.empty()) 32 { 33 if(s.top()=='('&&str[i]==')') 34 { 35 s.pop(); 36 } 37 else 38 s.push(str[i]); 39 } 40 else 41 { 42 s.push(str[i]); 43 } 44 } 45 if(s.empty()) 46 { 47 m++; 48 } 49 else 50 { 51 ll cpp=s.size(),flag=0; 52 while(!s.empty()) 53 { 54 if(s.top()=='(') 55 flag++; 56 s.pop(); 57 } 58 if(flag==0)//栈里面都是右括号 59 mp[-cpp]++; 60 else if(flag==cpp)//栈里面都是左括号 61 { 62 mp[cpp]++; 63 } 64 } 65 } 66 for(it=mp.begin();it!=mp.end();it++) 67 { 68 ll k=it->first; 69 if(mp.count(-k)) { 71 ans+=(ll)(it->second*mp[-k]);//左括号的种类*右括号的种类 72 } 73 } 74 printf("%lld\n",ans/2+m*m); 75 }
本文来自博客园,作者:左手边五十米,转载请注明原文链接:https://www.cnblogs.com/moomcake/p/9425384.html