2017-10-05
题目大意:
给出一串数字(P-sequence),分别表示一个仅由两两配对的左右括号队列(S)中,每个右括号之前的左括号数目。求位于每个右括号以及与它配对的左括号之间的右括号的数目(W-sequence)。
示例:
S (((()()())))
P-sequence 4 5 6666
W-sequence 1 1 1456
样例输入:
2
6
4 5 6 6 6 6
9
4 6 6 6 6 8 9 9 9
样例输出:
1 1 1 4 5 6
1 1 2 4 5 1 1 3 9
本题的关键在于记录括号的配对情况,因为一个左括号必然对应到一个右括号,所以把未配对的左括号位置压入堆栈,每出现一个右括号,即弹出栈顶(也就是离它最近的左括号)位置,便能方便地求出符合条件的右括号数目。
代码:
#include <iostream>
#include <stack>
using namespace std;
bool Pqueue[1000]; //构造括号队列
stack<int> paren;
int main() {
//kaseNum:输入样例组数; everyNum:每组输入样例的数据个数;
int kaseNum,everyNum;
cin >> kaseNum;
while(kaseNum > 0) {
//这里对Pqueue进行初始化是必须的,因为Pqueue是全局变量
memset(Pqueue,false,sizeof(Pqueue));
cin >> everyNum;
int tp,i;
int Rnum = 0; //记录右括号的个数
for(i = 0; i < everyNum; i++) {
cin >> tp;
//记录右括号的位置
Pqueue[tp+Rnum] = true;
Rnum++;
}
for(i = 0; i < Rnum+tp-1; i++) {
if(!Pqueue[i]) {
paren.push(i);
}
else
{
cout << (i - paren.top() + 1) / 2 << " ";
paren.pop();
}
}
cout << (i - paren.top() + 1) / 2 << endl;
paren.pop();
--kaseNum;
}
return 0;
}