ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 4354번 문자열 제곱
    문제 풀이 2020. 8. 29. 15:50

    4354 문자열 제곱


    문제


    알파벳 소문자로 이루어진 두 문자열 a와 b가 주어졌을 때, a*b는 두 문자열을 이어붙이는 것을 뜻한다. 예를 들어, a="abc", b="def"일 때, a*b="abcdef"이다.

    이러한 이어 붙이는 것을 곱셈으로 생각한다면, 음이 아닌 정수의 제곱도 정의할 수 있다.

    a^0 = "" (빈 문자열)

    a^(n+1) = a*(a^n)

    문자열 s가 주어졌을 때, 어떤 문자열 a에 대해서 s=a^n을 만족하는 가장 큰 n을 찾는 프로그램을 작성하시오.


    입력


    입력은 10개 이하의 테스트 케이스로 이루어져 있다. 각각의 테스트 케이스는 s를 포함한 한 줄로 이루어져 있다. s의 길이는 적어도 1이며, 백만글자를 넘지 않는다. 마지막 테스트 케이스의 다음 줄은 마침표이다.


    출력


    각각의 테스트 케이스에 대해, s=a^n을 만족하는 가장 큰 n을 찾은 뒤 출력한다.




    풀이)

    s = a^n, 가장 큰 n을 찾는게 목표이므로 반복되는 문자열의 최대길이가 아닌 최소길이를 찾아야한다.

    반복되는 최소 문자열 길이를 찾아 전체 문자열 길이그 길이로 나눈 답을 출력하면 된다.


    반복되는 문자열의 길이를 알아내기 위해서 KMP의 실패 함수를 이용했다.



    주의할 점

    처음에는 실패함수를 돌리고 난 후, 실패 함수 값이 0인 개수를 세어 그것을 전체 길이에 나눠서 답을 도출했다. 

    abcd, aaaa, ababab 같은 예시에는 정답이 나오나 반례가 존재했다.


    반례) abaaba  

    실패 함수값 F[i] : 0 0 1 1 2 3

    실제 정답: 6/3 =2     

    0인 개수 세었을 때 오류 정답: 6/2 =3


    실패 함수 값 중 0인 개수를 이용하는 것이 아닌 실패 함수의 마지막 값을 이용해야 한다.

    전체 길이 - 실패 함수의 마지막 값 = 반복되는 문자열의 최소 길이 이다.



    코드)

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    #include <stdio.h>
    #include <iostream>
    #include <string>
    using namespace std;
     
    int F[1000003];
    int main() {
        string s;
        while (true)
        {
            cin >> s;
            if (s == "."break;
            for (int i = 0; i < s.length(); i++) {
                F[i] = 0;
            }
            int i = 1;
            int j = 0;
            while (i<s.length())
            {
                if (s[i] == s[j]) {
                    F[i] = j + 1;
                    i += 1;
                    j += 1;
                }
                else if (j > 0) {
                    j = F[j - 1];
                }
                else {
                    F[i] = 0;
                    i += 1;
                }
            }
     
            int last = F[s.length() - 1];//마지막 값
            if (last == 0) {
                printf("1\n");
            }
            else {
                printf("%d\n", s.length() / (s.length() - last));
            }
            
        }
        return 0;
    }
    cs


    '문제 풀이' 카테고리의 다른 글

    [백준] 14442번 벽 부수고 이동하기2  (0) 2020.08.31
    [백준] 1701번 Cubeditor  (0) 2020.08.30
    [백준] 1786번 찾기  (0) 2020.08.28
    [백준] 1766번 문제집  (0) 2020.08.26
    [백준] 3665번 최종순위  (0) 2020.08.25

    댓글

Designed by Tistory.