题目大意:
对于一个良好组织的圆括号字符串S,有两种编码方式:
P方式:
P = p1 p2 … pn,这里pi是第i个右圆括号之前左圆括号的数量
W方式
W = w1 w2 … wn,这里举个例子,比如S中第i个右圆括号a,我们记录这个整数:从与a匹配的左圆括号数起,到a为止,中间右圆括号的数量。
要求从P编码转到W编码
思路:
这道题主要的难点在于理解题意:
本人比较笨,所以一步一步来。我们先根据P编码把原始S还原出来,用paren字符串数组记录。然后,我们再构造结果数组,用result数组记录。
具体构造过程如下:遍历数组,依次找出每个‘)’,然后从当前位置逆向查找,如果找到了一个‘(’,我们需要判断该‘(’是否已经配对,配对信息用used数组记录,如果已经配对,则说明该‘(’已经对应了一个‘)’,结果加1,否则该‘(’与‘)’配对,匹配找到,退出循环。最后,把结果打印出来
代码如下:
#include<stdio.h>
#include<memory.h>
int main()
{
int cases,n,a,b,x;
int i,j,k;
char paren[50],used[50];
int result[30];
scanf("%d",&cases);
while(cases--)
{
memset(used,0,sizeof(used));
for(i=0;i<30;++i)
result[i]=1;
scanf("%d",&n);
b=0;
j=0;
//还原S字符串
for(i=0;i<n;++i)
{
scanf("%d",&a);
if(a-b!=0){
for(k=0;k<a-b;++k)
{
paren[j]='(';
j++;
}
}
paren[j]=')';
j++;
b=a;
}
//构造W编码格式
x=0;
for(i=0;i<2*n;++i)
{
if(paren[i]==')')
{
for(j=i-1;j>=0;j--)
{
if(paren[j]=='(')
{
if(used[j]==1)
result[x]++;
else{
x++;
used[j]=1;
break;
}
}
}
}
}
//打印结果
for(i=0;i<n;++i){
printf("%d",result[i]);
if(i!=n-1)
printf(" ");
}
printf("\n");
}
return 0;
}