[PS] 백준 14405번 피카츄

박상혁·2026년 7월 3일

PS

목록 보기
66/95

이번에는 백준 14405번 피카츄 문제를 풀어보았습니다.

문제를 처음 봤을 때 문자열을 앞에서부터 읽으면서 "pi", "ka", "chu" 중 하나와 일치하는지만 확인하면 된다고 생각했습니다.

현재 위치에서 세 가지 문자열 중 하나가 시작되는지 확인하고, 일치한다면 해당 길이만큼 이동하는 방식으로 구현하였습니다.

이후에는 substr()을 이용하여 조금 더 간단하게 구현해보았습니다.


문제 설명

피카츄는 다음 세 음절만 발음할 수 있습니다.

  • "pi"
  • "ka"
  • "chu"

주어진 문자열이 위 세 음절만을 이어 붙여 만들 수 있는 문자열인지 판별하는 문제입니다.


풀이 아이디어

V1

현재 문자를 확인하여

  • p라면 "pi"
  • k라면 "ka"
  • c라면 "chu"

를 만족하는지 직접 검사하였습니다.

일치하면 해당 문자열 길이만큼 인덱스를 이동하고, 그렇지 않으면 발음할 수 없는 문자열이라고 판단하였습니다.

V2

같은 로직을 substr()을 이용하여 구현하였습니다.

현재 위치에서 "pi", "ka", "chu"와 같은지만 비교하면 되므로 코드가 훨씬 단순해졌습니다.


V1 코드

#include <bits/stdc++.h>
using namespace std;
string s;

int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> s;

    bool ret_flag = true;

    if (s.length() == 1)
        ret_flag = false;

    for (int i=0; i<s.length()-1; i++) {

        if (s[i] == 'p') {
            if (s[i+1] == 'i' && i != s.length()-3)
                i++;
            else
                ret_flag = false;
        }
        else if (s[i] == 'k') {
            if (s[i+1] == 'a' && i != s.length()-3)
                i++;
            else
                ret_flag = false;
        }
        else if (s[i] == 'c') {
            if (i != s.length()-2 && s[i+1] == 'h' && s[i+2] == 'u')
                i += 2;
            else
                ret_flag = false;
        }
        else {
            ret_flag = false;
        }
    }

    if (ret_flag)
        cout << "YES\n";
    else
        cout << "NO\n";

    return 0;
}

V1 풀이 흐름

  1. 문자열을 입력받습니다.
  2. 현재 문자를 확인합니다.
  3. pi, ka, chu 중 하나인지 검사합니다.
  4. 일치하면 해당 문자열 길이만큼 이동합니다.
  5. 일치하지 않으면 NO를 출력합니다.
  6. 끝까지 검사하면 YES를 출력합니다.

V1 구현 포인트

1. 첫 글자로 구분

현재 문자를 기준으로 어떤 문자열인지 판단하였습니다.

if (s[i] == 'p')
else if (s[i] == 'k')
else if (s[i] == 'c')

각 경우에 맞는 문자열을 직접 비교하도록 구현하였습니다.


2. 문자열 확인

각 문자열이 조건을 만족하는지 직접 확인하였습니다.

if (s[i+1] == 'i')
if (s[i+1] == 'a')
if (s[i+1] == 'h' && s[i+2] == 'u')

조건을 만족하지 않는 경우에는 바로 발음할 수 없는 문자열로 처리하였습니다.


3. 문자열 길이만큼 이동

현재 문자열을 정상적으로 읽었다면 해당 길이만큼 인덱스를 이동하였습니다.

i++;

또는

i += 2;

중복 검사 없이 다음 음절부터 확인하도록 구현하였습니다.


V2 코드

#include <bits/stdc++.h>
using namespace std;

int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    string s;
    cin >> s;

    bool ret_flag = true;

    for (int i = 0; i < s.length(); i++) {

        if (i < s.length()-1 &&
            (s.substr(i,2) == "pi" || s.substr(i,2) == "ka"))
            i++;

        else if (i < s.length()-2 &&
                 s.substr(i,3) == "chu")
            i += 2;

        else
            ret_flag = false;
    }

    if (ret_flag)
        cout << "YES\n";
    else
        cout << "NO\n";

    return 0;
}

V2 풀이 흐름

  1. 문자열을 입력받습니다.
  2. 현재 위치에서 "pi" 또는 "ka"인지 확인합니다.
  3. 아니라면 "chu"인지 확인합니다.
  4. 일치하면 문자열 길이만큼 이동합니다.
  5. 끝까지 검사하면 YES를 출력합니다.
  6. 중간에 하나라도 일치하지 않으면 NO를 출력합니다.

V2 구현 포인트

1. substr() 사용

현재 위치의 문자열을 직접 잘라 비교하였습니다.

if (s.substr(i,2) == "pi")
if (s.substr(i,2) == "ka")
if (s.substr(i,3) == "chu")

문자를 하나씩 비교하는 것보다 코드가 훨씬 간단해졌습니다.


2. 문자열 길이만큼 이동

문자열이 일치하면 길이만큼 인덱스를 증가시켰습니다.

i++;
i += 2;

이미 확인한 문자열을 다시 검사하지 않도록 구현하였습니다.


3. 범위 확인

substr()을 호출하기 전에 문자열 범위를 먼저 확인하였습니다.

if (i < s.length()-1)
if (i < s.length()-2)

문자열 범위를 벗어나는 경우가 발생하지 않도록 처리하였습니다.


V2는 V1과 동일한 로직이지만, substr()을 사용하여 문자열 비교를 단순화한 것이 핵심입니다.

profile
엉덩이로 성장하는 개발자

0개의 댓글