Parencodings POJ - 1068

Parencodings POJ - 1068

题目链接 :https://vjudge.net/problem/POJ-1068

题意:S是一个配对好的括号序列。P序列: P 1 P 2 P 3... P n , P i P1 P2 P3 ...Pn, Pi P1P2P3...Pn,Pi表示第i个右括号之前有多少个左括号。
W序列: W 1 , W 2 , W 3 , . . . W n W1,W2,W3,...Wn W1,W2,W3,...Wn Wi表示从 第 i 个 右 括 号 对 应 的 左 括 号 的 位 置 第i个右括号对应的左括号的位置 第i个右括号对应的左括号的位置 到 第 i 个 右 括 号 的 位 置 第i个右括号的位置 第i个右括号的位置有多少个右括号。
比如:

S		       (((()()())))

P-sequence	    4 5 6666

W-sequence	    1 1 1456

问题:给你P序列,求出W序列。

思路:读懂之后很容易。由P求出S,由S求出W,模拟这个过程即可。

具体见代码:

#include<iostream>
#include<stack>
using namespace std;
const int maxn=27;
int p[maxn];
int w[maxn];
int pa[maxn];
int r_pos[maxn];
stack<char>stk;
int getw(int id,string s){
	int res=0;
	int l=pa[id];
	int r=r_pos[id];
	//cout<<"l="<<l<<" r="<<r<<endl;
	for(int i=l;i<=r;i++){
		if(s[i]==')')res++;
	}
	//cout<<"res="<<res<<endl;
	return res;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		while(!stk.empty())stk.pop();
		int n;
		cin>>n;
		int i;
		p[0]=0;
		for(i=1;i<=n;i++){
			cin>>p[i];
		}
		//p-->s
		string s="";
		for(i=1;i<=n;i++){
			int j;
			int num=p[i]-p[i-1];
			for(j=1;j<=num;j++){
				s+='(';
			}
			s+=')';
		}
		//cout<<s<<endl;
		int tem=0;//l
		int sum=0;//r
		for(i=0;i<s.size();i++){
			if(s[i]=='(')stk.push(++tem);
			else{
				sum++;
				tem++;
				r_pos[sum]=i;
				int per=stk.top();
				stk.pop();
				pa[sum]=per;
			}
		}
		for(i=1;i<=sum;i++){
			pa[i]-=1;
		}
		for(i=1;i<=n;i++){
			w[i]=getw(i,s);
		}
		for(i=1;i<=n;i++){
			if(i!=n)cout<<w[i]<<" ";
			else cout<<w[i]<<endl;
		}
	}
	return 0;
}
上一篇:[PAT-A 1068]Find More Coins


下一篇:P5836 [USACO19DEC]Milk Visits S 从并查集到LCA(最近公共祖先) Tarjan算法