문제출처: https://www.acmicpc.net/problem/11899


문제

심심한 승현이는 너무 심심한 나머지 올바른 괄호열을 가지고 놀고 있었습니다.

(()(()))()()

그러다가 어쩌다 보니 괄호열을 부러뜨렸습니다.

(()    ((    )))()    ()

크게 낙담한 승현이는 노력해 보았지만, 대부분이 부러져 버려 단 한 부분만 재사용할 수 있다는 것을 깨닫게 되었습니다.

)))()

승현이는 이 괄호열을 가지고 놀려고 했으나 올바른 괄호열이 아니기 때문에 행복하지 않았습니다. 이를 보던 지학이는 승현이에게 “그러면 앞과 뒤에 적절하게 괄호를 붙이면 올바른 괄호열이 되지 않을까?”라고 했고, 승현이는 조금 생각한 뒤 그렇게 하기로 했습니다. 예를 들어, 위의 올바르지 않은 괄호열의 경우 앞에 여는 괄호 3개를 붙이면 올바른 괄호열이 됩니다.

((()))()

그러나 괄호열을 사서 붙이는 데에는 돈이 들고 많이 붙일수록 놀기가 불편해지기 때문에, 승현이는 가능한 한 괄호열을 적게 추가하려고 합니다.

승현이가 망가뜨리고 사용 가능한 올바르지 않은 괄호열이 주어질 때, 올바른 괄호열으로 만들기 위해 앞과 뒤에 붙여야 할 괄호의 최소 개수를 구하는 프로그램을 작성하세요.


입력

첫 번째 줄에 올바르지 않은 괄호열 S가 주어집니다. S의 길이는 1 이상 50 이하입니다.


출력

첫 번째 줄에 S를 올바른 괄호열으로 만들기 위해 앞과 뒤에 붙여야 할 괄호의 최소 개수를 출력합니다. 불가능한 경우는 주어지지 않습니다.


풀이

자료구조 책에서 다들 구현해봤을 괄호검사와 다를게없는 문제입니다. 어려운건 없지만 코드작성을 위해 알아야 할건 20행이 왼괄호만 해당된다는것28행이 오른괄호일 때 이므로(올바르지못한 수식일 때) 카운팅 해줘야한다는것입니다. 마지막으로 33행에서 스택에 남아있는 수만큼(왼괄호가 남아있을수 있음==필요한 오른괄호의 수) 다시 카운팅하는것으로 마무리합니다.


코드

#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main()
{
	string s;
	cin >> s;
	stack<char>st;
	int cnt = 0;
	for (int i = 0; i < s.size(); i++)
	{
		//비어있지 않을 떄
		if (!st.empty())
		{
			//올바른 짝일 때
			if (s[i] == ')' && st.top() == '(')
				st.pop();
			//아닐 때==왼괄호일떄  
			else
				st.push(s[i]);
		}
		//비어있을 때
		else
		{
			if (s[i] == '(')
				st.push(s[i]);
			else
				cnt++;
		}
	}
	//남아있는 왼괄호 갯수더해줌
	if (!st.empty())
		cnt += st.size();
	cout << cnt << endl;
}


결과

'문제풀이(BOJ) > 스택' 카테고리의 다른 글

[백준 3986] 좋은 단어  (0) 2019.12.08
[백준 9012] 괄호  (0) 2019.12.03
[백준 10828] 스택  (0) 2019.12.03

문제출처: https://www.acmicpc.net/problem/3986


문제

이번 계절학기에 심리학 개론을 수강 중인 평석이는 오늘 자정까지 보고서를 제출해야 한다. 보고서 작성이 너무 지루했던 평석이는 노트북에 엎드려서 꾸벅꾸벅 졸다가 제출 마감 1시간 전에 깨고 말았다. 안타깝게도 자는 동안 키보드가 잘못 눌려서 보고서의 모든 글자가 A와 B로 바뀌어 버렸다! 그래서 평석이는 보고서 작성을 때려치우고 보고서에서 '좋은 단어'나 세보기로 마음 먹었다.

평석이는 단어 위로 아치형 곡선을 그어 같은 글자끼리(A는 A끼리, B는 B끼리) 쌍을 짓기로 하였다. 만약 선끼리 교차하지 않으면서 각 글자를 정확히 한 개의 다른 위치에 있는 같은 글자와 짝 지을수 있다면, 그 단어는 '좋은 단어'이다. 평석이가 '좋은 단어' 개수를 세는 것을 도와주자.


입력

첫째 줄에 단어의 수 N이 주어진다. (1 ≤ N ≤ 100)

다음 N개 줄에는 A와 B로만 이루어진 단어가 한 줄에 하나씩 주어진다. 단어의 길이는 2와 100,000사이이며, 모든 단어 길이의 합은 1,000,000을 넘지 않는다.


출력

첫째 줄에 좋은 단어의 수를 출력한다.


풀이

페이지하단의 알고리즘분류의 스택을 힌트로얻어풀었습니다. 아치형 곡선이 교차 할 때와 교차하지 않을 때(정답이 아닐 때)는 아래의 그림과 같습니다.

스택이 비지않고 상단의 문자와 현재 문자가 같을때는 pop시키고, 그 외의 경우에는 삽입하면서 결과적으로 스택이 비어있으면 정답입니다.

 21~24행의 주석부분같은 실수만 조심하면됩니다.(ABBA일 때)


<겹칠 때> 

쌍을 맞추기 위해 단어의 배치를 바꿀 때 아래 경우처럼 무조건 겹침


<겹치지 않을 때>

최초: 안겹침. BB삭제 후 AA일때 안겹침


코드

#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main()
{
	int n;
	cin >> n;
	string s;
	int cnt = 0;
	for(int i=0;i<n;i++)
	{
		//순서가뒤바뀔때 엇갈리면안됨
		
		stack<char>st;
		cin >> s;
		for (int i = 0; i < s.size(); i++)
		{
			//if(st.empty())
			//st.push(s[i]);
			//else if(!st.empty()&&st.top()==s[i])
			//st.pop();
			if (!st.empty() && st.top() == s[i])
				st.pop();
			else
				st.push(s[i]);
		}
		if (st.empty())
			cnt++;
	}
	cout << cnt << endl;
}


결과



'문제풀이(BOJ) > 스택' 카테고리의 다른 글

[백준 11899] 괄호 끼워넣기  (0) 2020.01.08
[백준 9012] 괄호  (0) 2019.12.03
[백준 10828] 스택  (0) 2019.12.03

출처: https://www.acmicpc.net/problem/9012


풀이

저번에풀었던 10828번 문제 (https://jow1025.tistory.com/16)와 마찬가지로 스택을 이용한 괄호검사 문제로써 스택의 개념을 공부한 후 복습하기에 좋은 문제인 것같습니다. 이번문제는 c++의 스택stl을 이용하여 풀었습니다.

주의할점은 테스트케이스n을 입력후에 개행을 처리해주지않으면 n만입력해도 yes가출력됩니다. 

cin.ignore()로 해결하였고, 스택에 넣다가 입력할 문자가 오른괄호일 때  스택이 비어있지않고 스택의 최상단에 위치한 문자가 왼괄호 일때만 처리해주고 스택이 비어있을 시 즉시 빠져나와 NO를 출력하게합니다.


코드

#include<iostream>
#include<stack>
#include<string>
using namespace std;

int main()
{
	string s;
	int n;
	cin >> n;
	cin.ignore();
	while(n--)
	{
		stack<char>st;
		getline(cin, s);
	
		bool flag = true;
		if (s[0] == '.' && s.length() == 1)
			break;
		for (int i = 0; i < s.length(); i++)
		{
			if (s[i] == '(')
				st.push('(');
			else if (s[i] == '[')
				st.push('[');
			else if (s[i] == ']')
			{
				if (st.empty() == 0 && st.top() == '[')
					st.pop();
				else
				{
					flag = false;
					break;
				}
			}
			else if (s[i] == ')')
			{
				if (st.empty() == 0 && st.top() == '(')
					st.pop();
				else
				{
					flag = false;
					break;
				}
			}
		}
		if (flag == true && st.empty())
			cout << "YES" << '\n';
		else
			cout << "NO" << '\n';
	}
}


결과


'문제풀이(BOJ) > 스택' 카테고리의 다른 글

[백준 11899] 괄호 끼워넣기  (0) 2020.01.08
[백준 3986] 좋은 단어  (0) 2019.12.08
[백준 10828] 스택  (0) 2019.12.03

문제출처: https://www.acmicpc.net/problem/10828


풀이

전형적인 스택 구현 문제입니다. 스택의 개념을 공부하고 이 문제로 복습하면 좋을 것 같습니다.

본 풀이는 c언어스타일로 구현하였고 9012번문제https://www.acmicpc.net/problem/9012는 c++로 구현했습니다.


코드

#pragma warning (disable:4996)
#include<cstdio>
#include<cstring>
#define STACK_SIZE 10000
int stack[STACK_SIZE];
int top = -1;
void push(int num);
int is_full();
int is_empty();
int pop();
int count();
int peek();
int main()
{
	int n;
	scanf("%d", &n);
	int num;
	char choice[6];
	for (int i = 0; i < n; i++)
	{
		scanf("%s", choice);
		if (!strcmp(choice, "push"))
		{
			scanf("%d", &num);
			push(num);
		}
		else if (!strcmp(choice, "pop")) {
			if (top == -1)
				printf("-1\n");
			else
			{
				printf("%d\n", pop());
			}
		}
		else if (!strcmp(choice, "size"))
		{
			printf("%d\n", count());
		}
		else if (!strcmp(choice, "empty"))
		{
			printf("%d\n", is_empty());
		}
		else if (!strcmp(choice, "top"))
		{
			printf("%d\n", peek());
		}
	}
}
void push(int num)
{
	if (is_full())
		return;
	else stack[++top] = num;
}
int is_full()
{
	if (top == STACK_SIZE - 1)
		return 1;
	else return 0;
}
int is_empty()
{
	if (top == -1)
		return 1;
	else return 0;
}
int pop()
{
	if (is_empty())
		return -1;
	else return stack[top--];
}
int count()
{

	if (is_empty())
		return 0;
	else
	{
		return top + 1;
	}
}
int peek()
{
	if (is_empty())
		return -1;
	else return stack[top];
}


결과


'문제풀이(BOJ) > 스택' 카테고리의 다른 글

[백준 11899] 괄호 끼워넣기  (0) 2020.01.08
[백준 3986] 좋은 단어  (0) 2019.12.08
[백준 9012] 괄호  (0) 2019.12.03

+ Recent posts