알고리즘/문제 풀이
9935번: 문자열 폭발
Themion
2021. 12. 29. 16:03
https://www.acmicpc.net/problem/9935
9935번: 문자열 폭발
첫째 줄에 문자열이 주어진다. 문자열의 길이는 1보다 크거나 같고, 1,000,000보다 작거나 같다. 둘째 줄에 폭발 문자열이 주어진다. 길이는 1보다 크거나 같고, 36보다 작거나 같다. 두 문자열은 모
www.acmicpc.net
폭발 문자열을 찾을 문자열의 각 문자를 순서대로 스택 s에 넣은 뒤, 스택에서 문자를 하나씩 꺼내 다른 스택 s_에 차례로 저장한다. 이 때 폭발 문자열을 찾게 되면 s_에서 찾은 폭발 문자열을 제거한 뒤, 남은 s_를 모두 s에 저장한 뒤 다시 처음부터 폭발 문자열을 찾는다. 위 과정을 s가 빌 때까지 반복한 뒤 s_가 비었다면 FRULA를, 그렇지 않다면 s_를 차례로 출력하면 된다.
#include <iostream>
#include <stack>
using namespace std;
#define MAX_LEN 36
// from에서 to로 인자 하나를 옮긴다
void move(stack<char> &from, stack<char> &to) {
to.push(from.top());
from.pop();
}
int main() {
// 입출력 속도 향상
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// buf: 스택에 값을 넣기 위한 버퍼
// str: 폭발 문자열
char buf, str[MAX_LEN];
// len: 폭발 문자열의 길이, i: 폭발 문자열에 접근하기 위한 인덱스
int len = 0, i;
// s: 폭발 문자열을 찾을 문자열을 저장한 스택
// s_: s에서 출력할 값을 저장할 스택
stack<char> s, s_;
// 폭발 문자열을 찾을 문자열과 폭발 문자열을 입력받은 뒤
while ((buf = cin.get()) != '\n') s.push(buf);
for (; (str[len] = cin.get()) != '\n'; len++);
// 폭발 문자열에 접근할 인덱스를 초기화
i = len - 1;
// 스택 안의 모든 문자에 대해
while (!s.empty()) {
// s에서 폭발 문자열의 i번째 글자를 찾았다면 i를 1 줄이고,
// 그렇지 않다면 i를 len - 1로 맞춘 뒤 맨 마지막 글자만 비교
i = (s.top() == str[i]) ? i - 1 : len - 1 - (s.top() == str[len - 1]);
// s.top이 폭발 문자열의 문자든 아니든 우선 s_에 넣는다
move(s, s_);
// i가 음수라면, 즉 s에서 폭발 문자열을 모두 찾았다면
if (i < 0) {
// s_에서 폭발 문자열을 제거한 뒤
for (; i < len - 1; i++) s_.pop();
// s_에서 폭발 문자열의 마지막 글자까지, 혹은 s_ 전체를 원상복구해서
// 처음부터 다시 모든 과정을 반복
while (!s_.empty() && (!s.empty() && s.top() != str[len - 1]))
move(s_, s);
}
}
// s_가 비었다면 s는 폭발 문자열만으로 이루어져 있던 것이므로 "FRULA" 출력
if (s_.empty()) cout << "FRULA";
// 아니라면 s에서 폭발 문자열을 모두 제거한 결과를 출력
else while (!s_.empty()) {
cout << s_.top();
s_.pop();
}
// 개행 문자를 출력해 출력을 종료
cout << '\n';
return 0;
}