Removing Matched Parenthesis Pairs
National Olympiad — Regional round (2023 season)
Submission name: brackets.cpp
Problem summary
Remove one or more matched parenthesis pairs from a valid arithmetic expression. Print distinct resulting strings in lexicographic order; their numeric values may change.
Input
One valid expression without whitespace.
Output
Sorted distinct modified expressions, one per line.
Constraints
Length3…200;1…10 matched pairs; integer tokens and +,−,*,/ operations.
Worked example
Input and output for the worked example discussed below.
Input
(0/(0))
Output
(0/0) 0/(0) 0/0
Solution analysis
- Use a stack of opening positions to match each closing parenthesis with its unique opening. This gives the complete list of removable pairs.
- Enumerate every nonempty subset of pair indices, mark both endpoints for removal, and rebuild the expression from unmarked characters. At most1023 subsets are needed.
- An ordered set deduplicates outputs, since different subsets can produce the same string. For(0/(0)), removing the inner pair, outer pair, or both gives the displayed three results.
Why it works
Each legal removal selects a nonempty subset of original matched pairs, and every subset is enumerated. Reconstruction removes exactly those endpoints; the set keeps one copy of each result in order.
Watch out. Remove matched pairs, exclude the empty mask, and do not evaluate or preserve arithmetic values.
Commented C++17 solution
An independently written complete program with standard headers.
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<utility>
using namespace std;
// Each legal removal selects a nonempty subset of original matched pairs, and every subset is enumerated.
int main(){
string s;
cin>>s;
vector<int>openings;
vector<pair<int,int>>pairs;
for(int i=0;i<int(s.size());i++){
if(s[i]=='('){
openings.push_back(i);
}
else if(s[i]==')'){
pairs.push_back({openings.back(),i});
openings.pop_back();
}
}
set<string>answers;
for(int mask=1;mask<(1<<int(pairs.size()));mask++){
vector<bool>removed(s.size(),false);
for(int bit=0;bit<int(pairs.size());bit++){
if(mask&(1<<bit)){
removed[pairs[bit].first]=true;
removed[pairs[bit].second]=true;
}
}
string result;
for(int i=0;i<int(s.size());i++){
if(!removed[i]){
result.push_back(s[i]);
}
}
answers.insert(result);
}
for(const string&answer:answers){
cout<<answer<<'\n';
}
}