https://www.acmicpc.net/problem/1498
실패함수의 응용의 응용
반복되는 가장 작은 문자열 == 문제에서 원하는 "주기문" 의 길이를
https://blog.koderpark.dev/263
1305번의 아이디어에서 착안해서
$(N+1) - fail(N)$ 으로 구해줄 수 있으며,
X^n 꼴로 표현되는 가장 큰 수 K는
https://blog.koderpark.dev/264
4354번의 아이디어에서 착안해 와서
구해줄 수 있다.
즉 문제에서 요구하고있는 "주기문"인지에 대한 판별을
문자열의 길이 $N+1$ 이 주기문의 길이 $(N+1) - fail(N)$ (앞으로 $len$ 이라 하겠다)
로 나누어떨어지는지를 통해서 확인해줄 수 있다.
이렇게 확인해준 뒤에 문자열의 길이 $N+1$ 과 $N+1/len$ 를 출력해주면 정답을 받을 수 있다.
#include<bits/stdc++.h>
using namespace std;
int fail[1234567] = {0};
int main(){
string s;
cin >> s;
int N = s.length();
for(int i=1,j=0; i<N; i++){
while(j && s[i] != s[j]) j = fail[j-1];
if(s[i] == s[j]) fail[i] = ++j;
}
for(int i=1; i<N; i++){
int len = (i+1)-fail[i];
if(fail[i] && (i+1)%len == 0){
printf("%d %d\n", (i+1),(i+1)/len);
}
}
return 0;
}
오랜만에 kmp 잡아서 그런가 알?쏭달쏭한 문제였다
안한티가 팍팍나는군
반성을해야....
반응형