坑点较多,能过以下数据估计就可以了。
样例:
4
()
((((
(())
)))()(()))((()(((
输出:
1
0
2
4
首先,遍历一遍,计算“(”和“”的个数,取最小值记为ans。
然后,判断有没有“)(”这种字串,有的话,最终的串要转换为“...)))))(((((...”这种形式。
用两个数组:dp1从左到右计算“)”的个数前缀和;dp2从右往左计算“(”的个数后缀和。
遍历一遍,ans=min( ans , dp1[i] + dp2[i+1])。(详见代码)
/* Title :Scaena Felix Status:AC By wf,2015 9 27 */ #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <stack> #include <cmath> #include <queue> #include <set> #include <map> #define FOR(i,s,t) for(int i = (s) ; i <= (t) ; ++i ) typedef long long ll; using namespace std; const int inf=0x3f3f3f3f; const int maxn=1e3+5; int t; string s; int dp1[maxn],dp2[maxn]; int main() { cin>>t; while(t--){ cin>>s; memset(dp1,0,sizeof dp1); memset(dp2,0,sizeof dp2); int len=s.length(); bool ok=false; int ans; for(int i=0;i<len-1;++i){ if(s[i]==‘)‘ && s[i+1]==‘(‘)ok=true; } int n1=0,n2=0; for(int i=0;i<len;++i){ if(s[i]==‘(‘)n1++; else n2++; } ans=min(n1,n2); if(ok){ for(int i=0;i<len;++i){ if(i==0)dp1[i]=0; else dp1[i]=dp1[i-1]; if(s[i]==‘(‘)dp1[i]++; } for(int i=len-1;i>=0;i--){ if(i==len-1)dp2[i]=0; else dp2[i]=dp2[i+1]; if(s[i]==‘)‘)dp2[i]++; } for(int i=0;i<len-1;++i){ ans=min(ans,dp1[i]+dp2[i+1]); } } printf("%d\n",ans ); } return 0; }
时间: 2024-10-08 14:19:07