专栏文章
题解:CF2143E Make Good
CF2143E题解参与者 4已保存评论 3
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @minsg3j2
- 此快照首次捕获于
- 2025/12/02 07:36 3 个月前
- 此快照最后确认于
- 2025/12/02 07:36 3 个月前
怎么是简单题啊/崇拜
题目分析
考虑两种操作可以让我们干什么:
- 将
))替换为((。
我们先将所有
)) 替换为 ((。这样就可以得到 ..()(...()(... 这样的东西。考虑一个
),假设它右边是 ((,那么我们可以把它右移两位()(( ))) (())。考虑两个
) 会发生什么。比如说 )((),这时我们可以把中间两个翻转一下,变成 )))),然后再把左边两个和右边两个翻转,变成 ((((。所以我们得到:
-
可以将两个中间括号个数为偶数的
)都替换成(。 -
可以将
)在不越过其他)的时候移动偶数位。
于是我们维护哪些位置的
) 是不能变的。可以用一个栈维护,如果栈顶与当前之间的括号个数为偶数,那么就都弹出,否则加入。然后开始构造。由于要构造括号序列,就贪心地将
) 往后放。不妨先把所有 ) 移到左边,这时右边都是 ...(((( 的形式,从右往左翻转直到总右括号数量为 为止。为什么要假定把
) 移到左边:比如 (()(((,直接是不能把 ( 右移成 (((()(,这样会非常难解决;但如果我们先把它转化成 )((((( 这样就可以贪心在右边填 ))。然后再把所有左边的
) 尽可能移到右边就行了。最后可能还要再判下是否合法。根据实现决定吧。
Code
// by wangyizhi(571247)
#include<bits/stdc++.h>
//#include<bits/extc++.h>
//bool Mst;
using namespace std;
namespace wyzfastio{}
using namespace wyzfastio;
using ll=long long;
using ld=long double;
//#define int ll
using pii=pair<int,int>;
const int N=2e5+5;
int a[N];
//bool Med;
signed main()
{
// cerr<<"Memory Size: "<<abs((&Med)-(&Mst))/1024.0/1024<<" MB\n";
// ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
int t;read(t);
while(t--) [&]()->void
{
int n;string s;
read(n,s);
for(int i=0;i<=n+1;i++) a[i]=0;
stack<int> stk;
for(int i=0;i<n;i++) if(s[i]==')')
{
if(stk.size()&&(i-stk.top())&1) stk.pop();
else stk.push(i);
}
for(int i=n,j=1;j<=(n/2-(int)stk.size())/2*2;i--,j++) a[i]=1;
for(int lst=n-(n/2-(int)stk.size())+1;stk.size();)
{
if((lst^stk.top())&1) {if(lst>2)a[lst-=2]=1;}
else {if(lst>1)a[lst-=1]=1;}
stk.pop();
}
int p=0;
for(int i=1;i<=n;i++) if((p+=a[i]?-1:1)<0) return write("-1\n"),void();
if(p) return write("-1\n"),void();
for(int i=1;i<=n;i++) write(a[i]?')':'(');
write('\n');
}();
return 0;
}
相关推荐
评论
共 3 条评论,欢迎与作者交流。
正在加载评论...