티스토리 뷰

Algorithm/BOJ

[백준 1662] 압축

giiro 2020. 8. 31. 17:54

문제

www.acmicpc.net/problem/1662

 

1662번: 압축

압축되지 않은 문자열 S가 주어졌을 때, 이 문자열중 어떤 부분 문자열은 K(Q)와 같이 압축 할 수 있다. K는 한자리 정수이고, Q는 0자리 이상의 문자열이다. 이 Q라는 문자열이 K번 반복된다는 뜻이

www.acmicpc.net

 

문제 풀이

  • 괄호를 사용하는 전형적인 스택문제이므로 여는 괄호를 만났을 때, 그 앞의 숫자 K값을 담는 스택(벡터)를 하나 사용한다. 

  • 문자열을 처음부터 탐색할 때 (숫자,숫자), (숫자,여는괄호)와 같이 연속된 두 문자의 종류에 따라 길이에 더해지는 값이 달라지므로 편의상 문자를 두 개씩 보기로한다.

  •  해당 문자가 숫자일때, 스택(벡터)이 비어있다면 $Q$꼴이고 스택(벡터)이 비어있지 않다면 $K(Q)$꼴이라고 하자.


1. 현재 상태가 $Q$꼴인 경우 스택에 여는괄호가 없기 때문에 문자로 시작하는 경우는 존재하지않는다.

  1.  두 문자의 종류가 (숫자, 여는괄호)일 때 : 숫자가 새로운 K값이므로 스택에 넣어준다. // line 18

  2.  두 문자의 종류가 (숫자, 숫자)일 때 : 압축없이 길이만 증가하는 상태이므로 len을 1늘려줌 // line 19

2. 현재 상태가 $K(Q)$꼴인 경우 

  1. 두 문자의 종류가 (숫자(num), 여는괄호)일 때 : Q안에서 또 압축이 일어난 경우이므로 이전까지의 K값과 num을 곱해 스택에 넣어주고, 이전까지의 Q값을 이전까지의 K값(st.back())과 곱해서 len에 더해주고 q를 0으로 초기화 // line 25 ~28

  2. 두 문자의 종류가 (숫자, 숫자)일 때 : Q의 길이만 증가하는 상태이므로 q를 1늘려줌 // line 30

  3. 두 문자의 종류가 (여는 괄호, ~)일 때 : 앞서 2. 1번에서 여는괄호를 처리해줬기에 무시 // line 33

  4. 두 문자의 종류가 (닫는 괄호, 숫자)일 때 : 이전까지의 Q값을 이전까지의 K값과 곱해서 len에 더해주고 q를 0으로 초기화 // line 34 ~ 36

코드

#include <bits/stdc++.h>
using namespace std;

string str;
int l, len, num, q, k;
vector<int> st;

int main() {
	cin.tie(NULL); cout.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> str;
	l = str.length();
	for (int i = 0; i < l; i++) {
		num = str[i] - '0';
		if (st.empty()){
			if (isdigit(str[i])) {
				if (i + 1 < l && str[i + 1] == '(') st.push_back(num);
				else len++;
			}
		}
		else {
			if (isdigit(str[i])) { 
				if (i + 1 < l && str[i + 1] == '(') {
					k = st.back();
					st.push_back(num * k);
					len += q * k;
					q = 0;
				}
				else q++;
			}
			else {
				if (str[i] == '(') continue;
				k = st.back(), st.pop_back();
				len += q * k;
				q = 0;
			}
		}
	}
	cout << len;
}

'Algorithm > BOJ' 카테고리의 다른 글

[백준 19576] 약수  (0) 2020.08.31
[백준 19588] 상품권 준비  (0) 2020.08.31
[백준 19591] 독특한 계산기  (0) 2020.08.31
[백준 17080] 결함게임  (0) 2020.08.27
[백준 17143] 낚시왕  (0) 2020.08.16
댓글