T2 待思

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值