반응형
리뷰
https://www.acmicpc.net/problem/2800
그냥 되는데로 막 풀었는데 이게 왜 맞지? 싶었던 문제
수식의 길이가 짧고, 괄호 쌍이 많아야 10개라 시간 초과는 나지 않은 것 같다.
전역 변수
- n : 주어지는 수식의 길이를 저장할 변수
- cnt : 괄호 쌍의 개수를 저장할 변수
- si : 열린 괄호의 인덱스를 저장할 정수형 벡터
- ei : 닫힌 괄호의 인덱스를 저장할 정수형 벡터
- ans : 괄호를 제거한 문자열을 저장하기 위한 문자열 형식의 set
- s : 주어지는 수식을 입력 받을 문자열 변수
함수
1. bt
void bt(int level, string str)
괄호를 제거한 모든 수식을 탐색하기 위한 백트래킹 함수
- 매개 변수로 재귀 레벨 level과 현재 문자열 str을 입력 받는다.
- 만약 재귀가 한번이라도 진행된 상태라면 문자열을 set에 추가하는 작업을 진행한다.
- 빈 문자열 temp를 초기화 하고, str를 탐색하며 공백(' ')이 아닌 문자라면 temp에 더해준다.
- 위 조건을 만족하여 만들어진 문자열 temp를 ans에 insert해준다.
- level이 cnt에 도달하였다면 기저조건에 해당하므로 return을 해준다.
- 기저조건에 해당하지 않는다면 재귀 단계를 올려 bt를 실행해 준다. (문자열이 변경되지 않은 상태)
- 그 다음엔 level을 index로 사용해 si[level], ei[level]에 해당하는 인덱스를 문자열 str에서 공백으로 변경해준다.
- 한번 더 재귀 단계를 올려 bt를 실행해 준다. (문자열이 변경된 상태)
문제풀이
- 수식을 문자열 s에 입력 받아주고, n을 s의 크기로 저장해 준다.
- 괄호 정보를 저장하기 위한 정수형 벡터 stack을 초기화 해준다.
- n번의 반복문을 실행하고 문자열에서 '('를 만난 경우 스택에 인덱스를 추가해 준다.
- 만약 ')'를 만난 경우 si에 stack의 맨 뒤에 저장된 인덱스를 저장하고, ei에 현재 인덱스를 저장한다.
- 이후 스택의 맨 뒤 요소를 빼주고 cnt를 증가시켜 준다.
- bt 함수에 재귀 단계 0과 초기 문자열 s를 인자로 전달하여 백트래킹을 시작한다.
- 탐색을 마친 뒤 ans에 초기 문자열 s가 포함되어 있다면 제거해 준다.
- ans에 저장된 문자열을 줄 바꿈을 구분하여 출력해 준다.
참고 사항
오름 차순과 중복 제거를 사용하기 위해 set를 사용해 주었다.
다 풀고 나서 생각해 보니 백트래킹에서 level이 존재할 때만 ans에 추가해줄 필요는 없을 것 같다.(어차피 들어감)
따라서 백트래킹 후 초기 문자열은 꼭 ans에서 제거해 주어야 한다.
정답 코드
#include<iostream>
#include<set>
#include<vector>
using namespace std;
int n, cnt;
vector<int> si;
vector<int> ei;
set<string> ans;
string s;
void bt(int level, string str) {
if (level) {
string temp = "";
for (const char& ch : str) if (ch != ' ') temp += ch;
ans.insert(temp);
}
if (level == cnt) return;
bt(level + 1, str);
str[si[level]] = ' ';
str[ei[level]] = ' ';
bt(level + 1, str);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> s;
n = s.size();
vector<int> stack;
for (int i = 0; i < n; ++i) {
if (s[i] == '(') stack.push_back(i);
else if (s[i] == ')') {
si.push_back(stack.back());
ei.push_back(i);
stack.pop_back();
cnt++;
}
}
bt(0, s);
ans.erase(s);
for (const string r : ans) cout << r << "\n";
}
728x90
반응형
'알고리즘 공부 > C++' 카테고리의 다른 글
[G5] 백준 1240번 노드사이의 거리 C++ LCA, 트리 (0) | 2024.11.21 |
---|---|
[G5] 백준 2470번 두 용액 C++ 투 포인터, 정렬 (0) | 2024.11.20 |
[G4] 백준 1967번 트리의 지름 C++ DFS, 트리 (0) | 2024.11.18 |
[S1] 백준 28107번 회전초밥 C++ 큐 (2) | 2024.11.17 |
[G4] 백준 3078번 좋은 친구 C++ 큐, 슬라이딩 윈도우 (1) | 2024.11.16 |