题目描述:
S (((()()())))
P-sequence 4 5 6666
W-sequence 1 1 1456
p_seq代表遇到右括号时,左括号的数量;
w_seq表示遇到右括号时,算上自己和包含在匹配的括号里的一共匹配的括号有几对。
给出p_seq,求w_seq。
解题思路:
觉得自己的方法好绕口啊。。
最原始的想法就是用p_seq还原序列然后用堆栈来算匹配括号数。但是实现不靠谱因为序列可能很长。然后就观察给出的数的特点了。
利用给出的p_seq相邻数之间的差值delt来输出。若差值大于0说明左括号就在自己前面且未被匹配则直接输出1,否则说明要匹配的左括号在前面。那么在哪呢?就是在之前的某个下标处记录的delt还不为0的那个地方,就意味着那有左括号未被匹配。所以主要是索引回左括号所在位置的下标和此时右括号所在的下标差,即包含的匹配括号对数。
代码:
#include
#include
#define N 21
typedef struct{
int delt;
int pre_index;
}INDEX;
int p_seq[N], tmp_index;
INDEX index[N];
main(){
int t, i, n;
scanf("%d",&t);
while(t>0){
scanf("%d",&n);
scanf("%d",&p_seq[1]);
index[1].pre_index = 0;
index[1].delt = p_seq[1];
tmp_index = 1;
for(i=2;i<=n;i++){
scanf("%d",&p_seq[i]);
index[i].pre_index = tmp_index;
index[i].delt = p_seq[i] - p_seq[i-1];
if(index[i].delt > 1)
tmp_index = i;
}
//calc w_seq
printf("1");
index[1].delt --;
for(i=2;i<=n;i++){
if(index[i].delt > 0){
printf(" 1");
index[i].delt --;
}else{
while( index[index[i].pre_index].delt == 0){
index[i].pre_index = index[index[i].pre_index].pre_index;
}
index[index[i].pre_index].delt --;
printf(" %d",1+i-index[i].pre_index);
}
}
printf("\n");
t--;
}
system("pause");
return 0;
}