模拟 POJ 1068 Parencodings

时间:2023-03-09 17:37:14
模拟 POJ 1068 Parencodings

题目地址:http://poj.org/problem?id=1068

 /*
题意:给出每个右括号前的左括号总数(P序列),输出每对括号里的(包括自身)右括号总数(W序列)
模拟题:无算法,s数组把左括号记为-1,右括号记为1,然后对于每个右括号,numl记录之前的左括号
numr记录之前的右括号,sum累加s[i]的值,当sum == 0,并且s[i]是左括号(一对括号)结束,记录b[]记录numl的值即为答案
我当时题目没读懂,浪费很长时间。另外,可以用vector存储括号,还原字符串本来的样子
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <map>
#include <queue>
#include <vector>
using namespace std; const int MAXN = + ;
const int INF = 0x3f3f3f3f;
int a[MAXN];
int b[MAXN];
int s[]; void work(int n)
{
memset (s, , sizeof (s)); int k = a[];
for (int i=; i<=k; ++i) s[i] = -;
s[++k] = ; int cnt;
for (int i=; i<=n; ++i)
{
cnt = a[i] - a[i-];
for (int j=k+; j<=k++cnt; ++j)
{
s[j] = -;
}
k += cnt;
s[++k] = ;
}
int t = ;
for (int i=; i<=k; ++i)
{
if (s[i] == )
{
int sum = s[i];
int numl = , numr = ;
for (int j=i-; j>=; --j)
{
if (s[j] == ) numr++;
else numl++;
sum += s[j];
if (sum == )
{
b[++t] = numl; break;
}
}
}
}
int first = ;
for (int i=; i<=t; ++i)
{
if (first)
{
cout << b[i]; first = ;
}
else cout << " " << b[i];
}
cout << endl;
} int main(void) //POJ 1068 Parencodings
{
//freopen ("F.in", "r", stdin); int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i=; i<=n; ++i) cin >> a[i]; work (n);
} return ;
}