P1241 括号序列

考点

  • 模拟

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>
using namespace std;
const int LEN = 101;
bool match[LEN];
string s;
stack<int> st;

//如果是右括号,返回左括号
//如果是左括号,返回@
char get(char x)
{
if (x == ')')
return '(';
else if (x == ']')
return '[';
else
return '@';
}

int main()
{
cin >> s;
char lchr, rchr;
for (int i = 0; i < (int)s.length(); ++i)
{
if ((lchr = get(rchr = s[i])) == '@')
{
st.emplace(i);
continue;
}
if (st.empty())
continue;
int u = st.top();
if (s[u] == lchr)
{
st.pop();
match[u] = match[i] = 1;
}
}
for (int i = 0; i < (int)s.length(); ++i)
{
if (match[i])
cout << s[i];
else
{
if (s[i] == '(' || s[i] == ')')
cout << "()";
else
cout << "[]";
}
}
return 0;
}

思路

这道题的题面与样例简直就是大便...

根据题眼,如果它是一个右括号,考察它与它左侧离它最近的未匹配的的左括号

很显然左括号应该塞入栈,每次用右括号与栈顶的符号对比

  • 如果匹配成功,当前的右括号与栈顶的左括号都将自身的标志置为1,并弹出该左括号
  • 若不成功,继续下一次

若一个符号的标志为1,则说明可以正常输出;否则输出时要补全另一半

字符串的题目要考虑整串读入或逐字符读入哪个方便,本题应选择整串读入,因为要遍历