思 路 不 难 呀 , 实 现 起 来 会 比 较 容 易 漏 掉 细 节 思路不难呀,实现起来会比较容易漏掉细节 思路不难呀,实现起来会比较容易漏掉细节

注意三点

Ⅰ . 当 总 的 左 括 号 和 总 的 右 括 号 相 差 不 为 1 时 , 输 出 0 \color{Red}Ⅰ.当总的左括号和总的右括号相差不为1时,输出0 Ⅰ.当总的左括号和总的右括号相差不为1时,输出0

Ⅱ . 对 于 某 个 点 能 否 修 改 \color{Red}Ⅱ.对于某个点能否修改 Ⅱ.对于某个点能否修改

首 先 这 个 点 前 面 的 所 有 点 应 该 合 法 , 因 为 我 们 是 从 1 枚 举 到 n 首先这个点前面的所有点应该合法,因为我们是从1枚举到n 首先这个点前面的所有点应该合法,因为我们是从1枚举到n

不 合 法 就 直 接 退 出 了 , 所 以 不 用 考 虑 不合法就直接退出了,所以不用考虑 不合法就直接退出了,所以不用考虑

然 后 这 个 点 及 以 后 的 点 都 满 足 : 左 括 号 − 右 括 号 再 修 改 后 仍 然 大 于 0 然后这个点及以后的点都满足:左括号-右括号再修改后仍然大于0 然后这个点及以后的点都满足:左括号−右括号再修改后仍然大于0

那 么 其 实 只 要 右 边 的 左 括 号 减 右 括 号 的 最 小 值 满 足 条 件 即 可 那么其实只要右边的左括号减右括号的最小值满足条件即可 那么其实只要右边的左括号减右括号的最小值满足条件即可

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int a[maxn],n,pre[maxn],ans,maxx[maxn];
void over(){
cout<<0;
exit(0);
}
int main()
{
cin >> n ;
for(int i=1;i<=n;i++)
{
char s;
cin >> s;
s=='('?a[i]=1:a[i]=-1;
pre[i]=pre[i-1]+a[i];
}
maxx[n]=pre[n];
for(int i=n-1;i>=1;i--) maxx[i]=min(maxx[i+1],pre[i]);
if(pre[n]!=2&&pre[n]!=-2) over();
int sumn=0;
for(int i=1;i<=n;i++)
{
sumn+=a[i];
if(a[i]==1)
{
if(sumn<0) break;
if(pre[n]==-2) continue;//只能把)变成(
//现在把(改成了),也就是后面都减去2
if(maxx[i]-2>=0) ans++;
}
else//现在a[i]是-1
{
if(sumn<-2) break;//改变了也无济于事
if(pre[n]==2)
{
if(sumn<0) break;//后面就不可行啦
continue;//只能把(变成)
}
//现在把)改成了(,也就是后面都加上2
if(maxx[i]+2>=0) ans++;
if(sumn<0) break;//后面就不可行啦
}
}
cout<<ans;
}

精简版

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int a[maxn],n,pre[maxn],ans,maxx[maxn];
void over(){
cout<<0; exit(0);
}
int main()
{
cin >> n ;
for(int i=1;i<=n;i++)
{
char s;
cin >> s;
s=='('?a[i]=1:a[i]=-1;
pre[i]=pre[i-1]+a[i];
}
int sumn=pre[n];
if(sumn!=2&&sumn!=-2) over();
maxx[n]=sumn;
for(int i=n-1;i>=1;i--) maxx[i]=min(maxx[i+1],pre[i]);
for(int i=2;i<=n;i++)
pre[i]=min(pre[i-1],pre[i]);

for(int i=1;i<=n;i++)
{
if(a[i]==1)
{
if(pre[i-1]>=0&&maxx[i]>=2&&sumn==2) ans++;
}
else if(pre[i-1]>=0&&maxx[i]>=-2&&sumn==-2) ans++;
}
cout<<ans;
}