在餐厅买冰激凌的时候,因为等待的时间太无聊,所以园子和须美开始玩括号序列了。
园子首先给出一个括号序列,也就是一个只由「(」和「)」组成的字符串,然后须美需要在一秒之内通过翻转序列中的一些括号使得整个括号序列是合法的(也就是左右括号是相互匹配的)。
显然仅凭人类的力量想完成这个任务实在是太难了,所以须美想请你帮忙写一个程序帮她求出最少翻转几个括号才能让整个序列合法。
一次「翻转」的含义是改变序列中的某一确定位置的括号的方向。例如序列 ()))(),我们需要翻转第 2 个括号「)」,将其变成「(」,这样整个序列就变成了合法序列 (())(),总共需要翻转的次数为 1。
输入
输入共一行,为一个括号序列,序列长度 <= 107。
输出
最少翻转几个括号才能让整个序列合法,如果无论如何翻转都无法让序列合法则输出 -1。
样例输入
这 oj 居然不支持多样例? 样例输入1: (())( 样例输入2: )((()(
样例输出
样例输出1: -1 样例输出2: 3
提示
对于第二个样例,我们可以翻转第一个,最后一个和第四个括号使得序列变为 ((()))。
新生赛9
因为题中要求最少次数,因此我们在翻转时需要贯彻「能不翻就不翻」的基本准则。具体解法就是 声明⼀个 count 记录左括号数量,然后对序列从前往后扫,碰到左括号让 count + 1,碰到右括号让 count - 1,当 count < 0 的时候就意味着前⾯的右括号数量已经⼤于左括号了,这时必须要翻转⼀ 个括号,然后让 ans + 1。在扫完之后如果 count > 0 说明此时还有左括号剩余,需要再翻转 count / 2 个左括号使得序列合法。
int main() {
int counter = 0, ans = 0;
string str;
cin >> str;
if (str.length() & 1) {
cout << -1 << endl;
return 0;
}
for (int i = 0; i < str.length(); i++) {
if (str[i] == '(') counter++;
else counter--;
if (counter < 0) { counter += 2; ans++; }
}
ans += counter / 2;
cout << ans << endl;
return 0;
}