Koder / 박성훈
article thumbnail

오늘의 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;
}

반응형