문제 : https://www.acmicpc.net/problem/4354
문자열처리 KMP
KMP 알고리즘을 활용해 문자열 L 에서 반복되는 구간을 찾는 문제입니다.
문자열 L 이 임의의 문자열 T = "xxx" 가 n번 반복되서 만들어졌다고 가정합시다.
그럼 다음과 같은 사실이 무조건 성립합니다.
문자열 L 에서 접두사와 접미사가 같은 최대 길이 = | L | - | T |
즉, 접두사와 접미사가 최대로 같은 부분은 아래 그림과 같습니다.
따라서, 문자열 L의 최대 접두사와 접미사의 길이를 KMP 알고리즘을 이용해 구하고,
| L | 에서 빼준다면 | T | 를 구할 수 있습니다.
이때, | T | 의 제곱꼴로 | L | 이 이루어졌다면, | L | % | T | 가 0 이 성립해야합니다.
#include<iostream>
#include<vector>
using namespace std;
vector<int> getPartialMatch(string N) {
int m = N.size();
vector<int> pi(m, 0);
int begin = 1, matched = 0;
while (begin + matched < m) {
if (N[begin + matched] == N[matched]) {
matched++;
pi[begin + matched - 1] = matched;
}
else {
if (matched == 0) begin++;
else {
begin += matched - pi[matched - 1];
matched = pi[matched - 1];
}
}
}
return pi;
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
while (1) {
string L;
cin >> L;
int N = L.length();
if (L == ".") break;
vector<int> pi = getPartialMatch(L);
if (N % (N - pi[N - 1]) == 0)
cout << N / (N - pi[N - 1]) << '\n';
else {
cout << 1 << '\n';
}
}
return 0;
}
'Problem Solving > BOJ' 카테고리의 다른 글
[BOJ] 2671 : 잠수함 식별 (0) | 2020.05.15 |
---|---|
[BOJ] 1305 : 광고 (0) | 2020.05.08 |
[BOJ] 9935 : EKSPLOZIJA (0) | 2020.05.07 |
[BOJ] 1799 : 비숍 (0) | 2020.05.06 |
[BOJ] 9370 : Destination Unknown (0) | 2020.04.29 |