Algorithm/BOJ

[백준 1305] 광고 C++

Henu 2021. 7. 28. 00:26
 

1305번: 광고

세준이는 길 한가운데에서 전광판을 쳐다보고 있었다. 전광판에는 광고가 흘러나오고 있었다. 한참을 전광판을 쳐다본 세준이는 이 광고가 의미하는 것이 무엇인지 궁금해지기 시작했다. 전광

www.acmicpc.net

KMP


15분 정도 뚫어져라 본 결과 규칙을 찾았다.

 

문자열의 마지막이 접두사와 중복된 채로 끝난다면 해당 중복 문자열의 길이만큼 광고 문자열을 감소시킬 수 있다.

 

babba 라는 문자열이 주어졌다고 가정.

접두사 table을 만들어보자

table = {0, 0, 1, 1, 2}

테이블의 마지막 값이 2이므로 해당 문자열은 마지막 2개가 중복된다고 볼 수 있다.

따라서 문자열의 길이 5에서 중복 문자열 2개를 제외한 3개가 답이 된다. -> bab

다음 광고가 중복되는 부분부터 시작할 수 있기 때문

 

babbac 라는 문자열이 주어졌다고 가정.

접두사 table을 만들면 table = {0, 0, 1, 1, 2, 0}

테이블의 마지막 값이 0이므로 해당 문자열은 다음 광고판에 접두사로 이어지지 못한다.

따라서 최대 광고 길이는 6 - 0 = 6이 된다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
 
int L;
string text, pattern;
vector<int> table;
 
int main(){
    cin >> L >> text;
    pattern = text;
    table.resize(L+10);
    int j = 0;
    for(int i = 1; i < L; i++){
        while(j > 0 && pattern[j] != text[i]){
            j = table[j-1];
        }
        if(pattern[j] == text[i]){
            table[i] = ++j;
        }
    }
    
    cout << L - table[L-1];
    return 0;
}
 
cs