[Codeforces Round #288 (Div. 2)] -E Arthur and Brackets

32 篇文章 0 订阅
26 篇文章 0 订阅
洛谷传送门
Codeforces传送门

题意翻译

一个长为 2 n 2n 2n的括号序列,左括号和右括号都是 n n n个。

对于从左到右的第 i i i个左括号,对与其配对的右括号有如下限制:

与其配对的右括号和这个左括号之间的距离需要在 [ L i , R i ] [ L_i , R_i ] [Li,Ri] 之间。

输入的第一行给出 n ( 1 ≤ n ≤ 600 ) n(1\le n\le 600) n(1n600)

之后的 n n n行,给出限制: L i 、 R i L_i、R_i LiRi

如果满足限制的括号序列存在,输出任意一个即可。

否则输出"IMPOSSIBLE"(不包含引号)。

输入输出格式

输入格式

第一行一个正整数 n n n,表示括号对数。

以下 n n n行, 每行两个正整数, 表示 L i , R i L_i,R_i Li,Ri

输出格式

输出一个长度为 2 n 2n 2n的括号序列, 表示一个满足要求的序列。

输入输出样例

输入样例#1:
4
1 1
1 1
1 1
1 1
输出样例#1:
()()()()
输入样例#2:
3
5 5
3 3
1 1
输出样例#2:
((()))
输入样例#3:
3
5 5
3 3
2 2
输出样例#3:
IMPOSSIBLE
输入样例#4:
3
2 3
1 4
1 4
输出样例#4:
(())()

解题分析

看到括号序列想到栈, 发现如果要使前面一个左括号匹配上, 栈顶的括号就必须匹配上, 而栈顶的括号肯定能匹配就尽量先匹配(否则下面的容易超过 R i R_i Ri的限制), 这样贪心就好了。

代码如下:

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <algorithm>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 650
template <class T>
IN void in(T &x)
{
	x = 0; R char c = gc;
	for (; !isdigit(c); c = gc);
	for (;  isdigit(c); c = gc)
	x = (x << 1) + (x << 3) + c - 48;
}
char ans[MX];
struct INFO {int pos, l, r;}sta[MX];
int n, top, cnt;
int main(void)
{
	in(n); int l, r;
	for (R int i = 1; i <= n; ++i)
	{
		in(l), in(r);
		ans[++cnt] = '(';
		sta[++top] = {cnt, l, r};
		W (top)
		{
			if (sta[top].l + sta[top].pos <= cnt + 1 && sta[top].r + sta[top].pos >= cnt + 1)
			ans[++cnt] = ')', --top;
			else if (sta[top].r + sta[top].pos < cnt + 1) goto fail;
			else break;
		}
	}
	if (top) goto fail;
	return printf("%s", ans + 1), 0;
	fail:; puts("IMPOSSIBLE");
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值