Codeforces Challenge 2020B Kuroni and Simple Strings
题意:
对于一个字符串S,如果前半部分都是'(',后半部分都是')',那么它就是一个简单的字符串。
现在,你被赋予了一个由'('和')'组成的字符串,这个字符串不一定简单。
规定:每次操作可以从原字符串删除一个简单的子序列。
你的目标是找到最小的操作次数,使得剩下的字符串没有任何操作空间。
题解:
没有任何操作空间等价于所有符号全都背靠背)(.
等价于只删除一次,删除最大的简单序列即可。因为删除两次的话,一定可以合并。
所以输出第一行一定是1。
然后输出删除的子序列长度和每个元素的下标即可。
先统计出整个字符串右括号的数量。
然后遍历整个字符串,遇到一个右括号,就把右括号的数量加一,如果遇到左括号,就把左括号的数量减一。
当右括号的数量等于左括号时,就停止遍历,并记录下这个中间点,输出这个中间点左边所有的左括号,输出这个中间点右边所有的右括号。
#include<bits/stdc++.h> using namespace std; const int maxn=1014; string s; int main () { cin>>s; int suf=0; for (int i=0;i<s.length();i++) suf+=s[i]==')'; int pref=0; int cut=-1; for (int i=0;i<s.length();i++) { if (pref==suf) { cut=i; break; } if (s[i]=='(') pref++; else suf--; } vector<int> vi; for (int i=0;i<cut;i++) if (s[i]=='(') vi.push_back(i); for (int i=cut;i<s.length();i++) if (s[i]==')') vi.push_back(i); if (vi.empty()) printf("0\n"); else { printf ("1\n"); printf ("%d\n",vi.size()); for (int i=0;i<vi.size();i++) { if (i) printf (" "); printf ("%d",vi[i]+1); } printf ("\n"); } return 0; }