HDU-3351 Seinfeld(栈的简单用法)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41181771/article/details/86300787

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

扫描二维码关注公众号,回复: 4879105 查看本文章

}{

{}{}{}

{{{}

---

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;
}

猜你喜欢

转载自blog.csdn.net/qq_41181771/article/details/86300787