先对其预处理,对每个字符串,用栈消掉能匹配的括号,剩下的必然是 )))...((( 的形式。记录左括号数 l、右括号数 r、权值 v = l - r,以及前缀和最小值 mp。
判定合法性,如果全局 sum(l) != sum(r),直接 impossible。
那如何排序呢?
最后按排好的顺序累加前缀和,如果中途 sum + mp < 0,说明断链了,输出 impossible。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #include<bits/stdc++.h> using namespace std; #define int long long int n; struct node{ int v,l,r,mp,id; }a[1000001]; signed main(){ cin>>n; long long sl=0,sr=0; for(int i=1;i<=n;i++){ string s; cin>>s; stack<char>st; for(int j=0;j<s.size();j++){ if(s[j]=='(')st.push(s[j]); else{ if(!st.empty()&&st.top()=='(')st.pop(); else st.push(s[j]); } } int cur=0; while(!st.empty()){ char c=st.top(); st.pop(); if(c=='(')a[i].l++; else a[i].r++; } for(int j=0;j<s.size();j++){ if(s[j]=='(')cur++; else cur--; a[i].mp=min(a[i].mp,cur); } a[i].v=a[i].l-a[i].r,a[i].id=i; sl+=a[i].l,sr+=a[i].r; } if(sl!=sr){ cout<<"impossible\n"; return 0; } sort(a+1,a+n+1,[](const node&x,const node&y){ bool xa=x.r<=x.l; bool ya=y.r<=y.l; if(xa!=ya)return xa; if(xa)return x.r<y.r; return x.l>y.l; }); long long sum=0; for(int i=1;i<=n;i++){ if(sum+a[i].mp<0){ cout<<"impossible\n"; return 0; } sum+=a[i].v; } if(sum!=0){ cout<<"impossible\n"; return 0; } for(int i=1;i<=n;i++){ cout<<a[i].id<<endl; } }
|