合法的括号匹配序列被定义为:
1.空串“”是合法的括号序列
2.如果“X”和“Y”是合法的序列,那么“XY”也是一个合法的括号序列
3.如果“X”是一个合法的序列,那么“(X)”也是一个合法的括号序列
4.每个合法的括号序列都可以由上面的规则生成
例如””, “()”, “()()()”, “(()())”,”(((())))”都是合法的。现有一个合法的括号序列s,一次移除操作分为两步:
1. 移除序列s中第一个左括号
2.移除序列s中任意一个右括号,保证操作后s依旧合法
现想知道多少种方案可以把序列s变为空
如果两个方案中有意思移除操作移除的是不同的右括号即视为不同方案
例如:s=”()()()”输出1,因为每次都只能选择被移除的左括号相邻的右括号
s=”(((())))”,输出24,第一次有4种情况,第二次有3种情况…,依次类推,4*3*2*1=24
输入描述:一行,一个合法的括号序列s,长度length(2<=length<=20))
输出描述:一个整数,表示方案数
示例:
输入:
(((())))
输出:
24
思路:从样例中考虑右括号到左括号之间的右括号数目,记录下第k个右括号到第k个左括号之间有多少个右括号(包括第k个右括号本身),最后所有数目相乘得到结果
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main(){
string s;
cin>>s;
vector<int> count_left;
vector<int> count_right;
for(int i=0; i<s.size(); i++){
if(s.at(i)=='(‘)
count_left.push_back(i);
else
count_right.push_back(i);
}
vector<int> multi_nums;
for(int i=0; i<count_left.size(); i++){
int this_num = 1;
int begin_idx = count_left.at(i);
int end_idx = count_right.at(i);
for(int j=begin_idx+1; j<end_idx; j++){
if(s.at(j)==’)’)
this_num++;
}
multi_nums.push_back(this_num);
}
int result = 1;
for(int i=0; i<multi_nums.size(); i++)
result *= multi_nums.at(i);
cout<<result<<endl;
system(“pause”);
return 0;
}