洛谷传送门
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(1≤n≤600)。
之后的 n n n行,给出限制: L i 、 R i L_i、R_i Li、Ri。
如果满足限制的括号序列存在,输出任意一个即可。
否则输出"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");
}