Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 19191 | Accepted: 11575 |
Description
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
Output
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
Source
核心意思:
1.p序列:当出现匹配括号对时,从该括号对的右括号开始往左数,直到最前面的左括号数,就是pi的值。
2.w序列:当出现匹配括号对时,包含在该括号对中的所有右括号数(包括该括号对),就是wi的值。
思路:1.根据自己的出的结论,对于输入的数据,比如第一组是4 5 6 6 6 6,第一个数据4,也就是说在遇见第一个右括号时,左边有4个左括号str为“(((()”,对于第二个数据5,也就是说在遇见下一个右括号时,左边有5个左括号,str为“(((()()”,第三个数据6,说明遇见下一个右括号时左边有6个左括号(str为"(((()()()"),第四个数据6,说明又遇见一个右括号,它的左边有6个左括号(str为"(((()()())")...依次推下去,就能得到所有的括号:"(((()()())))"。。。
2.给出现的左括号依次标记,根据次序,每一个对应一个奇数
str:( ( ( ( ) ( ) ( ) ) ) )
bj: 1 3 5 7 -1 9 -1 11 -1 -1 -1 -1
这样做的目的是让和他们匹配的右括号是左括号+1,然后后面寻求在这个匹配的括号里面有多少个括号时,这两个紧挨着的数便是区间,只要统计出里面有多少奇数偶数,就知道有多少对匹配的括号了...
3.匹配,从bj[0],开始,然后遇到-1就开始往前找左括号,找到第一个并且ls[]数组标记为0的左括号,然后把ls[]标记为1,说明它被匹配了,然后把右括号的bj[](本来是-1)置为左括号bj[]+1(是一个偶数),把所有的都匹配完
str:( ( ( ( ) ( ) ( ) ) ) )
bj: 1 3 5 7 8 9 10 11 12 6 4 2
4.从前往后找右括号,在右括号和左括号这个区间(我们用bj[]数组来找)统计其中的奇数和偶数的数量,去最小,放入记录数组,然后打印出来就ok了...
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
using namespace std;
char str[1010];//这个数组是用来保存还原的括号
int ls[1010];//这个是用来标记左括号是已经被匹配
int bj[1010];//这个是用来标记左括号和右括号的
int k=0;//这个变量是用来记录生成的str数组的长度
void sc1(int x)
{
while(x--)
{
str[k++]='(';
}
}
void sc2()
{
str[k++]=')';
}
void cz(int j)
{
int x=j;
for(;j>=0;j--)
{
if(str[j]=='('&&ls[j]==0)
{
bj[x]=bj[j]+1;
ls[j]=1;
return ;
}
}
}
int main()
{
int t,i,j,js,os,x;
int n,s[1010];
cin>>t;
while(t--)
{
memset(str,'\0',sizeof(str));
memset(bj,-1,sizeof(bj));
memset(ls,0,sizeof(ls));
k=0;
cin>>n;
for(i=0;i<n;i++)
{
cin>>s[i];//接收输入的数
}
sc1(s[0]);
sc2();
for(i=1;i<n;i++)
{
sc1(s[i]-s[i-1]);
sc2();
}//根据得出的结论,写出算法实现
j=1;
for(i=0;i<k;i++)
{
if(str[i]=='(')
{
bj[i]=j;
j+=2;
}
}//把左括号按先后顺序标记为奇数
for(i=0;i<k;i++)
{
if(bj[i]==-1)
{
cz(i);
}
}//左右括号匹配
x=0;
for(i=0;i<k;i++)
{
if(str[i]==')')
{
js=0;
os=0;
j=i;
for(;j>=0;j--)
{
if(bj[j]%2==0)
{
os++;
}
if(bj[j]%2==1)
{
js++;
}
if(bj[j]==bj[i]-1)
{
break;
}
}
s[x++]=os<js?os:js;
}
}//统计中间有多少个成对的括号
for(i=0;i<x;i++)
{
cout<<s[i];
if(i<x-1)
cout<<" ";
}
cout<<endl;
}
return 0;
}