오늘의 KMP 그 두번째 문제
https://www.acmicpc.net/problem/4354
4354번: 문자열 제곱
알파벳 소문자로 이루어진 두 문자열 a와 b가 주어졌을 때, a*b는 두 문자열을 이어붙이는 것을 뜻한다. 예를 들어, a="abc", b="def"일 때, a*b="abcdef"이다. 이러한 이어 붙이는 것을 곱셈으로 생각한다
www.acmicpc.net
반복되는 가장 작은 문자열의 길이를 https://blog.koderpark.dev/263
1305번 풀이와 동일하게 구해준 다음,
( 문자열의 길이 / 반복되는 가장 작은 문자열의 길이 )
로 구해줄 수 있다.
이때, 코너케이스가 있는데, 나눈 나머지를 보는 방법도 있다고 하지만
나는 그냥 입력받은 문자열을 두배로 이어붙여서 나온 값을 다시 2로 나누었다.
이 경우에는 자기 자신 또한 길이 두배 문자열의 접두사 / 접미사가 될 수 있으므로 AC를 받을 수 있다.
소스코드 펼쳐보기
더보기
#include <bits/stdc++.h>
using namespace std;
int fail[2345678]= {0};
int main(){
string s;
while(cin >> s){
if(s == ".") break;
s = s+s;
memset(fail, 0, sizeof(fail));
int N = s.length();
for(int i=0,j=1; j<N; j++){
while(i && s[i] != s[j]) i = fail[i-1];
if(s[i] == s[j]) fail[j] = ++i;
}
int tmp = (N)-fail[N-1];
cout << N/tmp/2 << "\n";
}
return 0;
}
반응형