1. 程式人生 > >HDU-3351 Seinfeld(棧的簡單用法)

HDU-3351 Seinfeld(棧的簡單用法)

Sourse:題目連結

                                              Seinfeld

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2448    Accepted Submission(s): 1144

Problem Description

I’m out of stories. For years I’ve been writing stories, some rather silly, just to make simple problems look difficult and complex problems look easy. But, alas, not for this one.
You’re given a non empty string made in its entirety from opening and closing braces. Your task is to find the minimum number of “operations” needed to make the string stable. The definition for being stable is as follows:
1. An empty string is stable.
2. If S is stable, then {S} is also stable.
3. If S and T are both stable, then ST (the concatenation of the two) is also stable.
All of these strings are stable: {}, {}{}, and {{}{}}; But none of these: }{, {{}{, nor {}{.
The only operation allowed on the string is to replace an opening brace with a closing brace, or visa-versa.

 

Input

Your program will be tested on one or more data sets. Each data set is described on a single line. The line is a non-empty string of opening and closing braces and nothing else. No string has more than 2000 braces. All sequences are of even length.
The last line of the input is made of one or more ’-’ (minus signs.)


 

Output

For each test case, print the following line:
k. N
Where k is the test case number (starting at one,) and N is the minimum number of operations needed to convert the given string into a balanced one.
Note: There is a blank space before N.

 

Sample Input

}{

{}{}{}

{{{}

---

Sample Output

1. 2

2. 0

3. 1

題意解析:

需要把所有的括號,都使它有匹配的括號,也就是必須是 “{}” “{}{}{}” 這樣才行,而我們的目的就是使原來不規則的大括號們,都變成有 物件” 的大括號,然後輸出需要進行的運算元,每次操作,你可以使右括號變成左括號,或者相反操作。

輸入一堆左右大括號,然後輸出樣例次數和需要幾次操作才能完成所有括號的匹配。

主要思路:

第一次輸入,直接進行匹配,用棧頂元素跟即將進棧的元素匹配,若匹配成功,則元素不進棧,且將棧頂元素丟擲,匹配完以後,剩下進棧的情況,則只有三種,有 “}}}}}}” 、“{{{{{{” 、“ }}}}}}{{{{{”。這樣的話,可以用 flag1 來記右括號的數量,flag2來記左括號的數量,即為(flag1,0)、(0,flag2)、(flag1,flag2);然後左右分開處理。

 

就 “}}{{” 這個例子來說 }}  {{ 這樣分兩塊,第一塊需要一次,第二塊需要一次

則總處理次數=右括號的數量 / 2 +左括號的數量 / 2 ;                     (1)

 

就 “}}}{{{” 這個例子來說 }}} {{{ 這樣分兩塊,第一塊需要一次,第二塊需要一次,加起來的話,結果是2;但是事實證明,兩次並不能完成這個匹配,它需要四次,因為 “}}}{{{” 將它 }} {} {{ 這樣分三塊,第一塊需要一次,第二塊需要兩次,第三塊需要一次故如果左右括號都為奇數個的時候(題上說括號總數為偶數)

則總處理次數=(右括號的數量 + 1)/ 2 +(左括號的數量 + 1)/ 2 ;                     (2)

因為(int)/ 2 的機制是向下取整,所以可以直接用第二個公式

程式碼篇:

#include <iostream>
#include <cstring>
#include <stack>
using namespace std;
stack <char> s; ///建立一個空棧,進棧元素型別為char
int main()
{
    char arr[1000];
    int t = 1;
    while(cin >> arr)
    {
        int flag1 = 0, flag2 = 0;
        if(arr[0] == '-')
            break;
        for(int i = 0; i < strlen(arr); i++)
        {
            if(s.empty()) ///若為空棧,則將當前元素進棧
            {
                s.push(arr[i]);
            }
            else if(s.top() + 2 == arr[i]) ///若棧頂元素跟當前元素匹配,丟擲棧頂元素
            {                              ///ASCII碼中, '}' - '{' = 2;
                s.pop();
            }
            else ///不能匹配的話,則壓棧;
            {
                s.push(arr[i]);
            }
        }
        while(!s.empty()) ///棧不為空時,元素出棧
        {
            if(s.top() == '{')
                flag1 ++;
            else
                flag2 ++;
            s.pop();
        }
        cout << t++ << ". ";
        cout << (flag1 + 1) / 2 + (flag2 + 1) / 2 << endl;
    }
    return 0;
}