[백준 2800번 C/C++] 괄호 제거
[백준 2800번 C/C++] 괄호 제거
https://www.acmicpc.net/problem/2800
해결전략
문자열
재귀
비트마스킹 Bitmasking
정답코드 1 - 비트마스킹 사용
#include <iostream>
#include <set>
#include <stack>
#include <vector>
using namespace std;
string input; // 문제에서 주어진 문자열
int n;
vector<pair<int, int>> brackets; // 괄호 한 쌍의 위치를 저장
set<string> results; // 만들 수 있는 문자열을 기록
// 괄호 쌍의 위치를 찾는 함수
void FindBrackets()
{
stack<int> bracketLocation;
// 문자열을 순회하며 괄호 쌍을 찾음
for (int i = 0; i < input.size(); i++)
{
if (input[i] == '('){
bracketLocation.push(i); // '(' 위치를 스택에 저장
}
else if (input[i] == ')'){
int openBracketLocation = bracketLocation.top(); // 마지막으로 열린 괄호 위치를 가져옴
bracketLocation.pop(); // 스택에서 '(' 제거
brackets.push_back({ openBracketLocation, i }); // 괄호 쌍의 위치를 벡터에 저장
}
}
}
// 재귀적으로 문자열을 생성하는 함수
void Generate(int idx, string str, const vector<int> ch)
{
if (idx == n){
results.insert(str);
return;
}
if (ch[idx] == 1) // idx 위치의 문자 생략
{
Generate(idx + 1, str, ch);
}
else // idx 위치의 문자 추가
{
Generate(idx + 1, str + input[idx], ch);
}
}
// 가능한 모든 괄호 조합을 생성하는 함수
void Cal()
{
for (int bitmask = 1; bitmask < (1 << brackets.size()); bitmask++)
{
vector<int> ch(n, 0); // 문자를 제거할지 여부를 표시하는 벡터 (0: 유지, 1: 제거)
// bitmask의 각 비트를 확인하여 괄호 쌍을 제거할지 결정
for (int i = 0; i < brackets.size(); i++)
{
if (bitmask & (1 << i)) { // 비트마스크의 i번째 비트가 설정되어 있으면
ch[brackets[i].first] = 1; // 여는 괄호 위치를 제거로 표시
ch[brackets[i].second] = 1; // 닫는 괄호 위치를 제거로 표시
}
}
Generate(0, "", ch); // 현재 제거 설정에 따라 문자열을 생성
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> input;
n = input.size();
FindBrackets(); // 괄호 쌍의 위치를 찾음
Cal(); // 괄호 조합을 이용하여 문자열을 생성
for (const auto& iter : results)
{
cout << iter << "\n";
}
return 0;
}
정답코드 2
#include <iostream>
#include <set>
#include <stack>
#include <vector>
using namespace std;
string input; // 문제에서 주어진 문자열
int n;
vector<pair<int, int>> brackets; // 괄호 한 쌍의 위치를 저장
set<string> results; // 만들 수 있는 문자열을 기록
void FindBrackets()
{
stack<int> bracketLocation;
for (int i = 0; i < input.size(); i++)
{
if (input[i] == '('){
bracketLocation.push(i);
}
else if (input[i] == ')'){
int openBracketLocation = bracketLocation.top();
bracketLocation.pop();
brackets.push_back({ openBracketLocation, i });
}
}
}
void Generate(int idx, string str, const vector<int> ch)
{
if (idx == input.size()){
results.insert(str);
return;
}
if (ch[idx] == 1) // idx 위치의 문자 생략
{
Generate(idx + 1, str, ch);
}
else // 문자 생략X
{
Generate(idx + 1, str + input[idx], ch);
}
}
void CalHelper(int cnt, vector<int>& ch)
{
if (cnt == brackets.size()) {
Generate(0, "", ch);
return;
}
// 현재 괄호 쌍을 제거하지 않는 경우
CalHelper(cnt + 1, ch);
// 현재 괄호 쌍을 제거하는 경우
ch[brackets[cnt].first] = 1;
ch[brackets[cnt].second] = 1;
CalHelper(cnt + 1, ch);
ch[brackets[cnt].first] = 0;
ch[brackets[cnt].second] = 0;
}
void Cal()
{
vector<int> ch(n, 0);
CalHelper(0, ch);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> input;
n = input.size();
FindBrackets();
Cal();
int i = 0;
for (const auto& iter : results)
{
i++;
if (i == 1) continue;
cout << iter << "\n";
}
return 0;
}
정답코드 3
#include <iostream>
#include <set>
#include <stack>
#include <vector>
#include <string>
using namespace std;
string input;
set<string> results;
vector<pair<int, int>> brackets;
void Generate(int idx, string str, vector<int>& ch)
{
if (idx == input.size()){
results.insert(str);
return;
}
if (ch[idx] == 1){
Generate(idx + 1, str, ch);
}
else if (ch[idx] == 0){
Generate(idx + 1, str + input[idx], ch);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> input;
// 괄호 위치 구하기
stack<int> bracketLoc;
for (int i = 0; i < input.size(); i++)
{
if (input[i] == '('){
bracketLoc.push(i);
}
else if (input[i] == ')'){
int openLoc = bracketLoc.top();
bracketLoc.pop();
brackets.push_back({ openLoc, i });
}
}
// 전체 경우의 수 1 << brackets.size() - 1
for (int bitmask = 1; bitmask < (1 << brackets.size()); bitmask++)
{
vector<int> ch(input.size(), 0);
for (int i = 0; i < brackets.size(); i++)
{
if (bitmask & (1 << i)){
ch[brackets[i].first] = 1;
ch[brackets[i].second] = 1;
}
}
Generate(0, "", ch);
}
// 결과 출력
for (const auto& iter : results){
cout << iter << "\n";
}
return 0;
}
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 16938번 C/C++] 캠프 준비 (0) | 2024.08.02 |
---|---|
[백준 2961번 C/C++] 도영이가 만든 맛있는 음식 (0) | 2024.08.01 |
[백준 15787번 C/C++] 기차가 어둠을 헤치고 은하수를 (0) | 2024.07.30 |
[백준 14569번 C/C++] 시간표 짜기 (0) | 2024.07.29 |
[백준 14503번 C/C++] 로봇 청소기 (0) | 2024.07.28 |
댓글
이 글 공유하기
다른 글
-
[백준 16938번 C/C++] 캠프 준비
[백준 16938번 C/C++] 캠프 준비
2024.08.02 -
[백준 2961번 C/C++] 도영이가 만든 맛있는 음식
[백준 2961번 C/C++] 도영이가 만든 맛있는 음식
2024.08.01 -
[백준 15787번 C/C++] 기차가 어둠을 헤치고 은하수를
[백준 15787번 C/C++] 기차가 어둠을 헤치고 은하수를
2024.07.30 -
[백준 14569번 C/C++] 시간표 짜기
[백준 14569번 C/C++] 시간표 짜기
2024.07.29