题目链接
大意:给你n个区间,第 i个区间 [li,ri]表示和第 i个左括号相匹配的右括号和这个左括号距离的范围。让你输出一种合法的序列。
思路:对于每一个右括号,和他相匹配的左括号肯定是离得最近的左括号。那么我们用栈进行模拟。对每个左括号先压入栈中,然后每次讨论栈顶元素,看是否可以放右括号,即栈顶元素的位置与放置右括号的位置满足这个左括号的区间要求。如果已经超过了范围就显然不成立,若还没到左区间的要求,就break.处理下一个左括号。
细节见代码
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back
using namespace std;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
const int N = 2e5 +11;
stack<int>q;
int pos[N],n,cnt,l[N],r[N];
char ans[N];
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>l[i]>>r[i];
pos[i]=cnt;
ans[++cnt]='(';
q.push(i);
while(!q.empty()){
int now=q.top();
if(pos[now]+l[now]>cnt)break;
if(pos[now]+r[now]<cnt){
return cout<<"IMPOSSIBLE\n",0;
}
q.pop();
ans[++cnt]=')';
}
}
if(q.empty()){
for(int i=1;i<=cnt;i++)cout<<ans[i];cout<<endl;
}else cout<<"IMPOSSIBLE\n";
return 0;
}