括号配对

在餐厅买冰激凌的时候,因为等待的时间太无聊,所以园子和须美开始玩括号序列了。 

园子首先给出一个括号序列,也就是一个只由「(」和「)」组成的字符串,然后须美需要在一秒之内通过翻转序列中的一些括号使得整个括号序列是合法的(也就是左右括号是相互匹配的)。 

显然仅凭人类的力量想完成这个任务实在是太难了,所以须美想请你帮忙写一个程序帮她求出最少翻转几个括号才能让整个序列合法。  

一次「翻转」的含义是改变序列中的某一确定位置的括号的方向。例如序列 ()))(),我们需要翻转第 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;
}

 

转载于:https://www.cnblogs.com/RenoStudio/p/10355184.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值