백준 9935 문자열 폭발
문제
문자열에 “폭발 문자열”이 들어 있으면 그 부분이 사라지고, 남은 양쪽이 다시 붙는다. 이 폭발은 더 이상 터질 게 없을 때까지 연쇄적으로 일어난다. 모든 폭발이 끝난 뒤 남은 문자열을 구하면 된다.
- 입력: 1번째 줄에 문자열, 2번째 줄에 폭발 문자열.
- 출력: 폭발이 끝난 뒤 남은 문자열. 남은 게 없으면
FRULA. - 제한: 문자열 길이 ≤ 1,000,000, 폭발 문자열 길이 ≤ 36, 둘 다 영문 대소문자와 숫자로만 이루어짐.
접근
폭발은 연쇄적이다. 한 번 터져서 양쪽이 붙으면 거기서 또 터질 수 있다. 그래서 매번 문자열 전체를 다시 훑어 폭발 문자열을 찾는 식으로 풀면, 최악엔 문자열을 몇 번이고 다시 스캔하게 돼서 길이가 100만일 때 시간 초과가 난다.
스택으로 한 번만 훑으면 된다. 문자를 앞에서부터 하나씩 스택에 쌓되, 쌓을 때마다 스택의 맨 위 (폭발 문자열 길이)개가 폭발 문자열과 같은지 본다. 같으면 그만큼 스택에서 빼낸다(pop). 이렇게 하면 “빼낸 뒤 위아래가 붙어서 또 터지는” 연쇄 폭발이 자연스럽게 처리된다 — 스택 맨 위는 항상 “현재까지 살아남은 문자열의 끝”이니까.
코드에서는 char 배열을 스택으로 쓰고 j를 스택 꼭대기로 삼았다. 새 문자를 넣은 뒤, 끝 글자가 폭발 문자열의 마지막 글자와 같고 길이가 충분하면 뒤에서부터 폭발 문자열과 비교하고, 전부 맞으면 j를 폭발 문자열 길이만큼 줄여 한 번에 제거한다. 마지막에 남은 게 없으면 FRULA.
풀이
전체 코드: thxwelchs/algorithm
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 백준 9935 문자열 폭발
// https://www.acmicpc.net/problem/9935
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
string N, P;
char a[1000000];
cin >> N >> P;
int strSize = N.size(), bombSize = P.size();
int j = 0;
int count = 0;
for(int i = 0; i < strSize; i++) {
a[j++] = N[i];
if (a[j - 1] == P[bombSize - 1] && j >= bombSize) {
int o = 0;
bool isAllMatch = true;
for (int x = bombSize - 1; x >= 0; x--) {
if (a[j - 1 - (bombSize - 1 - x)] != P[x]) {
isAllMatch = false;
break;
}
}
if (isAllMatch) {
count++;
j -= bombSize;
}
}
}
if(count * bombSize == strSize) {
cout << "FRULA";
return 0;
}
for(int i = 0; i < strSize - count * bombSize; i++) {
cout << a[i];
}
return 0;
}
댓글
GitHub(giscus) 댓글은 설정 완료 후 활성화됩니다.