题目描述:
给出一个括号序列,规定一下两种编码形式:
1)P-sequence:P = p1 p2 ... pn,其中pi表示第i个右括号左边的左括号个数;
2)W-sequence:W = w1 w2 ... wn,其中wi表示在第i个右括号和与之相匹配的左括号之间的右括号个数(包括第i个右括号)
算法描述:
1)将输入的P-sequence转换成对应的括号序列S;
2)根据序列S转换出对应的W-sequence并输出;
把由P-sequence转换出的括号序列左括号用-1表示,右括号用1表示,然后遍历整个序列,遇到1(右括号)则从当前位置往前搜索,寻找与之匹配的-1(左括号),匹配过程中把每一对匹配后的括号分别标记为-2(匹配后的左括号)和2(匹配后的右括号),这样直接统计每次匹配过程中经过的值为2的元素数量即可得到W-sequence每一位的数值。
给出一个括号序列,规定一下两种编码形式:
1)P-sequence:P = p1 p2 ... pn,其中pi表示第i个右括号左边的左括号个数;
2)W-sequence:W = w1 w2 ... wn,其中wi表示在第i个右括号和与之相匹配的左括号之间的右括号个数(包括第i个右括号)
示例如下:
括号序列S: ( ( ( ( ) ( ) ( ) ) ) ) //相匹配的括号用相同颜色标出
对应的P-sequence: 4 5 6 6 6 6
给出一个序列的P-sequence,要求输出对应的W-sequence对应的W-sequence: 1 1 1 4 5 6
算法描述:
1)将输入的P-sequence转换成对应的括号序列S;
2)根据序列S转换出对应的W-sequence并输出;
把由P-sequence转换出的括号序列左括号用-1表示,右括号用1表示,然后遍历整个序列,遇到1(右括号)则从当前位置往前搜索,寻找与之匹配的-1(左括号),匹配过程中把每一对匹配后的括号分别标记为-2(匹配后的左括号)和2(匹配后的右括号),这样直接统计每次匹配过程中经过的值为2的元素数量即可得到W-sequence每一位的数值。
例如:
P-sequence: 4 5 6 6 6 6
转换成括号序列S:( ( ( ( ) ( ) ( ) ) ) )
把上面的括号序列编码:-1 -1 -1 -1 1 -1 1 -1 1 1 1 1
匹配过程如下:
1)遍历到第一个 1(右括号),向前寻找最近的未匹配过的左括号(-1),并将匹配到的1置为2,-1置为-2,得到第一次匹配后的序列为:-1 -1 -1 -2 2 -1 1 -1 1 1 1 1,该过程中右括号数 w1 = 1;
2)按照1)的方法,第二次匹配后的序列:-1 -1 -1 -2 2 -2 2 -1 1 1 1 1, w2 = 1;
3) 第三次匹配后的序列:-1 -1 -1 -2 2 -2 2 -2 2 1 1 1, w3 = 1;
4) 第四次匹配后的序列:-1 -1 -2 -2 2 -2 2 -2 2 2 1 1, w4 = 4;
5) 第五次匹配后的序列:-1 -2 -2 -2 2 -2 2 -2 2 2 2 1, w5 = 5;
6) 第五次匹配后的序列:-2 -2 -2 -2 2 -2 2 -2 2 2 2 2, w6 = 6;
Code:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 100;
int main()
{
int t, n;
int indx[maxn];
int numvis[maxn];
scanf( "%d", &t );
for( int i = 0; i < t; i++ )
{
scanf( "%d", &n );
for( int j = 1; j <= n; j++ )
scanf( "%d", &indx[j] );
indx[0] = 0;
int co = 1;
for( int j = 1; j <= n; j++ )
{//把输入的 P-sequence 转换成对应的左右括号序列,左括号用-1表示,右括号用1表示
if( indx[j] - indx[j-1] == 0 )
{
numvis[co++] = 1;
}
else
{
for( int k = 0; k < indx[j] - indx[j-1]; k++ )
{
numvis[co++] = -1;
}
numvis[co++] = 1;
}
}
bool blank = 0;
for( int j = 1; j < co; j++ )
{
if( numvis[j] == 1 )
{//遍历转换后的序列,遇到右括号寻找与之匹配的左括号并按题目要求计数,并对匹配完的括号做标记
int ans = 1;
for( int k = j-1; k >= 1; k-- )
{
if( numvis[k] == -1 )
{
numvis[k] = -2;
numvis[j] = 2;
break;
}
else
{
k -= 1;
ans++;
}
}
if( !blank )
{
printf( "%d", ans );
blank = 1;
}
else
printf( " %d", ans );
}
}
printf( "\n" );
}
return 0;
}