2017.10.3 国庆清北 D3T1 括号序列

题目描述

LYK有一个括号序列,但这个序列不一定合法。

一个合法的括号序列如下:

()是合法的括号序列。

若A是合法的括号序列,则(A)是合法的括号序列。

若A和B分别是合法的括号序列,则AB是合法的括号序列。

LYK想通过尽可能少的操作将这个不一定合法的括号序列变成合法的括号序列。一次修改操作是将某个字符变成另一个字符。

你能帮帮它吗?

输入输出格式

输入格式:

一行一个字符串S。

输出格式:

一个数表示最少修改次数。

输入输出样例

输入样例#1:
()))
输出样例#1:
1

样例解释
将第二个字符修改成(即可。

说明

对于30%的数据|S|<=10。 对于60%的数据|S|<=1000。 对于100%的数据|S|<=100000。且|S|是偶数。

 1 /*从左往右扫过来,遇到一个),观察之前有没有(,如果有的话就抵消掉。
 2 如果没有的话 -> 把这个字符变成(,操作次数数++
 3 一直这么做,扫完整个字符串之后,最终一定匹配完后剩下一堆左括号或者不剩下,
 4 然后将这些左括号的一半改为右括号,就可以完成整个操作了。所以操作次数+=剩下的左括号数/2。
 5 所以,总的操作次数=改掉的右括号个数+剩下的左括号个数/2。
 6 */
 7 #include<iostream>
 8 #include<cmath>
 9 #include<cstdio>
10 #include<cstring>
11 #include<algorithm>
12 using namespace std;
13 
14 int ans,tot,len,flag;
15 char s[100001];
16 
17 int main()
18 {
19     freopen("bracket.in","r",stdin);
20     freopen("bracket.out","w",stdout);
21     scanf("%s",s);
22     len=strlen(s);
23     for(int i=0;i<len;i++)
24     {
25         if(s[i]=='(') tot++;    //记录左括号个数 
26         else tot--;        //用右括号抵消掉 
27         if(tot<0)    //如果没有左括号,就把当前括号改为左括号 
28         {
29             tot=1;        //因为是把右括号改成了左括号,所以现在有1个左括号 
30             ans++;        //操作次数++ 
31         }
32     }
33     if(tot) ans+=tot/2;        //剩下的左括号个数,除以2,把一半的左括号变成右括号 
34     printf("%d",ans);
35     fclose(stdin);
36     fclose(stdout);
37     return 0;
38 }
View Code
原文地址:https://www.cnblogs.com/lovewhy/p/7651947.html