题目地址:http://poj.org/problem?id=1068
1 /*
2 题意:给出每个右括号前的左括号总数(P序列),输出每对括号里的(包括自身)右括号总数(W序列)
3 模拟题:无算法,s数组把左括号记为-1,右括号记为1,然后对于每个右括号,numl记录之前的左括号
4 numr记录之前的右括号,sum累加s[i]的值,当sum == 0,并且s[i]是左括号(一对括号)结束,记录b[]记录numl的值即为答案
5 我当时题目没读懂,浪费很长时间。另外,可以用vector存储括号,还原字符串本来的样子
6 */
7 #include <cstdio>
8 #include <iostream>
9 #include <algorithm>
10 #include <cstring>
11 #include <cmath>
12 #include <string>
13 #include <map>
14 #include <queue>
15 #include <vector>
16 using namespace std;
17
18 const int MAXN = 100 + 10;
19 const int INF = 0x3f3f3f3f;
20 int a[MAXN];
21 int b[MAXN];
22 int s[1000];
23
24 void work(int n)
25 {
26 memset (s, 0, sizeof (s));
27
28 int k = a[1];
29 for (int i=1; i<=k; ++i) s[i] = -1;
30 s[++k] = 1;
31
32 int cnt;
33 for (int i=2; i<=n; ++i)
34 {
35 cnt = a[i] - a[i-1];
36 for (int j=k+1; j<=k+1+cnt; ++j)
37 {
38 s[j] = -1;
39 }
40 k += cnt;
41 s[++k] = 1;
42 }
43 int t = 0;
44 for (int i=1; i<=k; ++i)
45 {
46 if (s[i] == 1)
47 {
48 int sum = s[i];
49 int numl = 0, numr = 0;
50 for (int j=i-1; j>=1; --j)
51 {
52 if (s[j] == 1) numr++;
53 else numl++;
54 sum += s[j];
55 if (sum == 0)
56 {
57 b[++t] = numl; break;
58 }
59 }
60 }
61 }
62 int first = 1;
63 for (int i=1; i<=t; ++i)
64 {
65 if (first)
66 {
67 cout << b[i]; first = 0;
68 }
69 else cout << " " << b[i];
70 }
71 cout << endl;
72 }
73
74 int main(void) //POJ 1068 Parencodings
75 {
76 //freopen ("F.in", "r", stdin);
77
78 int t;
79 cin >> t;
80 while (t--)
81 {
82 int n;
83 cin >> n;
84 for (int i=1; i<=n; ++i) cin >> a[i];
85
86 work (n);
87 }
88
89 return 0;
90 }