POJ 1068(模拟)

题目链接:http://poj.org/problem?id=1068


题意:一个括号表达式可以按照如下的规则表示,就是每个右括号之前的左括号数。比如(((()()()))),每个右括号之前的左括号数序列为P=4 5 6 6 6 6,而每个右括号所在的括号内包含的括号数为W=1 1 1 4 5 6.现在给定P,输出W。

思路:直接模拟。根据p先模拟出原来的合式公式,然后从右向左判断匹配所有的右括号,具体代码实现如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn=110;
int T,n,m;
char s[maxn];
int a[20];

int main(){
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
#endif
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(int i=0;i<n;i++){
			scanf("%d",&a[i]);
		}
		int leftNum=0;
		int index=0;
		for(int i=0;i<n;i++){
			if(leftNum<a[i]){
				while(leftNum<a[i]){
					leftNum++;
					s[index++]='(';
				}
			}
			s[index++]=')';
		}
		int tmp=n-1;
		for(int i=index-1;i>=0;i--){
			if(s[i]=='(') continue;
			else{
				int parNum=0;
				a[tmp]=1;
				for(int j=i-1;j>=0;j--){
					if(s[j]==')')
						a[tmp]++;
					else{
						parNum++;
						a[tmp]--;
					}
					if(a[tmp]==0){
						a[tmp]=parNum;
						break;
					}
				}
				tmp--;
			}
		}
		for(int i=0;i<n;i++)
			printf("%d%c",a[i],i==n-1?'\n':' ');
	}
    return 0;
}


你可能感兴趣的:(POJ 1068(模拟))