The Monster
题目大意:
给出一个串,只包含 ( ? ) 三种符号,求出有多少个子串是完美匹配的.
比如
( ) ? ) => ( ) ( ) 完美匹配
( ( ) ? => ( ( ) )完美匹配
? ? ? ? => ( ) ( )
=> ( ( ) )
算一种子串
length<5000 ,1000ms
分析:
这个长度和时间限制比较诡异,想不到比较好的方法,猜想应该是在 n2 上的基础上做一点优化.结果确实是这样的
枚举两个端点没有试过,可能会超时
枚举起点开始往后遍历,做标记
if (
cnt++
else if )
cnt--
else
f++
cnt++
先把 ? 当 ( 算
如果 ) 太多了 break
如果 ? 可以取到值 使得这个子串成立, 答案++;
这样就做完了
并没有
少了关键的一步没做出来… 如果仅仅是按照这样小关系来算会出现错误
原因在于每次得到的都是当前位置的最终结果 并不知道先后顺序 使得 ? ( 和 ( ? 的处理情况一样 都会使得答案+1
但是先后顺序是没法得到的,怎么避免 ? ( 的情况呢
容易想到 ? ( 中 ? 不可能是未知量 而是确定的 (
在判断的之前先把能确定下的 ? 全部确定下来,剩下的全是可变的 ? ,再判断能否按照题目要求变化即可.
具体实现:
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define inf 0x3f3f3f3f
#define mem(s,t) memset(s,t,sizeof s)
typedef pair<int,int> pii;
typedef long long ll;
const int MAXN =1e5+10;
int main() {
string s;
cin>>s;
int cnt=0,f=0,ans=0;
for(int i=0;i<s.size();i++){
cnt=0,f=0;
for(int j=i;j<s.size();j++){
if(s[j]=='('){
cnt++;
}
else if(s[j]==')'){
cnt--;
}
else {
f++;
cnt++;
}
if(cnt<0) break;
f=min(f,cnt/2);//最多需要 cnt/2个 的 ?来参与变化 其他的?都是可确定量
if(cnt%2==0 && cnt/2<=f) ans++;//长度为偶数 && 可以取到 cnt/2的值
}
}
cout<<ans<<endl;
return 0;
}