Parencodings
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 20763 | Accepted: 12480 |
Description
Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in two different ways:
q By an integer sequence P = p1 p2...pn where pi is the number of left parentheses before the ith right parenthesis in S (P-sequence).
q By an integer sequence W = w1 w2...wn where for each right parenthesis, say a in S, we associate an integer which is the number of right parentheses counting from the matched left parenthesis of a up to a. (W-sequence).
Following is an example of the above encodings:
Write a program to convert P-sequence of a well-formed string to the W-sequence of the same string.
q By an integer sequence P = p1 p2...pn where pi is the number of left parentheses before the ith right parenthesis in S (P-sequence).
q By an integer sequence W = w1 w2...wn where for each right parenthesis, say a in S, we associate an integer which is the number of right parentheses counting from the matched left parenthesis of a up to a. (W-sequence).
Following is an example of the above encodings:
S (((()()()))) P-sequence 4 5 6666 W-sequence 1 1 1456
Write a program to convert P-sequence of a well-formed string to the W-sequence of the same string.
Input
The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case is an integer n (1 <= n <= 20), and the second line is the P-sequence of a well-formed string. It contains n positive integers, separated with blanks, representing the P-sequence.
Output
The output file consists of exactly t lines corresponding to test cases. For each test case, the output line should contain n integers describing the W-sequence of the string corresponding to its given P-sequence.
Sample Input
2 6 4 5 6 6 6 6 9 4 6 6 6 6 8 9 9 9
Sample Output
1 1 1 4 5 6 1 1 2 4 5 1 1 3 9
解题思路:
本题为模拟题,为了简单化,可以把括号转化成0和1存储,0代表左括号,1代表右括号,根据推理可得如下公式:location = a[i] + i,location代表右括号的位置,也就是现在1所在的位置,可以转化成0和1的串,最后再用回溯法,把括号进行配对,配对完成的置为访问过,边配对边输出结果,一直到所有的都配对完。在poj上本题用c++提交wrong answer,用g++ Accepted,本题槽点略多,看poj 的discuss就知道了。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 500;
const int maxn1 = 500;
int a[maxn];
int m;
void change()
{
int b[maxn1];
int vis[maxn1];
int i,j;
int location;
int temp;
int k;
int pos;
int cnt;
memset(b,-1,sizeof(b));
memset(vis,0,sizeof(vis));
/*for(i=0;i<300;i++)
{
b[i] = -1;
}
for(i=0;i<300;i++)
{
vis[i] = 0;
}*/
temp = 0;
cnt = 0;
for(i=0;i<m;i++)
{
location = a[i] + i; //计算右括号的位置
for(j=temp;j<=location;j++)
{
b[j] = 0;
temp = location + 1;
}
b[location] = 1;
}
k = 0;
while(b[k] != -1)
{
k++; //0,1一共的个数
}
for(i=0;i<k;i++)
{
if(b[i] == 1)
{
for(j=i-1;j>=0;j--)
{
if(b[j] == 0 && vis[j] == 0)
{
vis[i] = 1;
vis[j] = 1;
pos = i-j+1;
cnt++;
if(cnt == 1)
cout<<pos/2;
else
cout<<" "<<pos/2;
break;
}
}
}
}
cout<<endl;
}
int main()
{
int T;
int i;
//freopen("111","r",stdin);
cin>>T;
while(T--)
{
cin>>m;
for(i=0;i<m;i++)
{
cin>>a[i];
}
change();
}
return 0;
}