1. 程式人生 > >2017.10.3 國慶清北 D3T1 括號序列

2017.10.3 國慶清北 D3T1 括號序列

iostream lose style scan bfd algo 字符 數據 fclose

題目描述

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

2017.10.3 國慶清北 D3T1 括號序列