7-2 括号
分数 20
作者 tan60
单位 兰州大学
一名A国特工历经千难万险,终于偷取到了S国某机密部门控制核弹发射的lisp程序代码的最后一页,来不及多想,他把这张纸揣在怀里快速逃离。
等到他逃到了相对安全的地点,他迫不及待地打开这张纸,却看到了比十亿核弹更恐怖的东西。
这页的内容是:
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
上面是一个关于lisp语言的笑话,现在,为了抚慰特工受伤的幼小心灵,我们需要构造合法的括号序列,使得特工下次不必面对一页写满右括号的纸。
可以由以下三条定义出所有合法的(小)括号序列:
1.空串是合法的
2,如果a,b是合法串,则ab也是合法串
3,如果a是合法串,则(a)也是合法串
对于一个括号序列s,我们这样定义一个匹配上的括号对(i,j)
1.s[i]=(
2.s[j]=)
3.s[i+1..j−1]是一个合法括号序列
如()(())中有三个匹配上的括号对(1,2),(3,6),(4,5)
现给出2n个数{ai},ai对应位置i上的括号权值,一个匹配上的括号对(i,j)权值是∣ai−aj∣
请构造一个合法括号序列使得它所有的匹配上的括号对权值和最大
输入格式:
第一行一个整数n
第二行2n个整数表示ai
输出格式:
输出满足要求的括号序列
若果有多个输出一个即可
样例1:
2
1 2 3 4
(())
样例2:
2
2 3 2 3
()()
数据范围
1≤N≤2×105
1≤Ai≤109
样例解释
长度为4(=2×2)的括号序列有两种()(), (())
第一个样例中
(())权值为4=∣2−3∣+∣1−4∣
()()权值为2=∣1−2∣+∣3−4∣
第二个样例中
(())权值为2=∣3−2∣+∣2−3∣
()()权值为2=∣2−3∣+∣2−3∣
故两者答案均可
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#include <utility>
std::string constructMaxWeightParentheses(int n, const std::vector<int>& a) {
std::stack<std::pair<int, int>> stack; // 存储左括号的索引和权值
std::vector<std::pair<int, int>> matches; // 存储匹配的括号对
std::string result(2 * n, ' '); // 初始化结果字符串
for (int i = 0; i < 2 * n; ++i) {
if (i % 2 == 0) {
// 左括号,压入栈中
stack.push({a[i], i});
} else {
// 右括号,弹出栈顶元素并构造匹配对
auto left = stack.top();
stack.pop();
matches.push_back({left.second, i});
}
}
// 根据匹配对填充结果字符串
for (const auto& match : matches) {
result[match.first] = '(';
result[match.second] = ')';
}
return result;
}
int main() {
int n;
std::cin >> n;
std::vector<int> a(2 * n);
for (int i = 0; i < 2 * n; ++i) {
std::cin >> a[i];
}
std::string parentheses = constructMaxWeightParentheses(n, a);
std::cout << parentheses << std::endl;
return 0;
}