Algorithm/PS

[1일 1알고] G5 2011 암호코드

Basaeng 2026. 3. 26. 15:11

https://www.acmicpc.net/problem/2011

 

 

"정답이 매우 클 수 있으므로, 1000000으로 나눈 나머지를 출력한다."

라는 문장이 있는 것으로 보아 모든 경우를 직접 계산하는 것은 아니고, dp를 통해 계산하게 될 것임을 알 수 있습니다.

 

11이라면 AA 혹은 K로 해석될 수 있습니다.

따라서 현재 시점에서 숫자를 따로 해석하는 경우와 합쳐서 해석하는 경우를 나눠서 보아야 합니다.

 

그렇다면 index i일  따로 해석하는 경우에는 i-1 시점의 경우의 수, 같이 해석하는 경우는 i-2 시점의 경우의 수와 같기 때문에

전체 경우의 수 dp[i] = dp[i-1] + dp[i-2]가될 것입니다.

 

하지만 이것은 숫자가 따로 + 합쳐서 해석이 가능한 경우에만 그렇고 모든 경우를 따져봐야합니다.


1. 숫자가 1~9인 경우  (따로 해석만 가능한 경우)

숫자가 1~9인 경우는 i-1(i>=2)의 숫자가 0인 경우입니다. 앞의 숫자가 0이기 때문에 해당 숫자는 0앞의 숫자와 묶여서 해석되었을 것이고 따라서 해당 시점에서는 dp[i] = dp[i-1]입니다.


2. 숫자가 합쳐서 해석 가능한 두자리 수 인 경우 (다만 숫자 != 10 || 숫자 != 20)

숫자가 따로 + 합쳐서 해석 가능한 경우는 숫자가 두자리 수이며 알파벳 범위 안에 있는 10 ~ 26인 경우입니다.

다만 10이나 20인 경우는 한 자리 수가 0이기 때문에 별도의 경우로 보아야 합니다.

 

이 경우에는 위에서 언급한 dp[i] = dp[i-1] + dp[i-2]입니다.


3. 숫자가 10혹은 20으로 해석되어야 하는 경우 (합쳐서만 해석이 가능한 경우)

30, 40 ....는 알파벳 범위 밖에 있기 때문에 이 경우에는 해석이 불가합니다.

10, 20인 경우에는 이렇게 해석하지 않으면 해석이 실패하기 때문에 i-1번째 해석을 무시하고 i-2시점의 경우의 수만 받아옵니다.

따라서 dp[i] = dp[i-2]입니다.


코드

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;



int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string s;
    cin >> s;
    int size = s.size();
    vector<long long> v(size, 0);

    v[0] = 1;

    if (s[0] == '0')
    {
        cout << 0;
        return 0;
    }
    else if (size == 1)
    {
        cout << 1;
        return 0;
    }

    if (s[1] == '0')
    {
        if (s[0] == '1' || s[0] == '2')
        {
            v[1] = 1;
        }
        else
        {
            cout << 0;
            return 0;
        }
    }
    else if ((s[1 - 1] - '0') * 10 + (s[1] - '0') <= 26)
    {
        v[1] = 2;
    }
    else
    {
        v[1] = 1;
    }


    for (int i = 2; i < size; ++i)
    {
        int temp = (s[i - 1] - '0') * 10 + (s[i] - '0');
        if (s[i] == '0')
        {
            if (s[i - 1] == '1' || s[i - 1] == '2')
            {
                v[i] = v[i - 2] % 1000000;;
            }
            else
            {
                v[size - 1] = 0;
                break;
            }
        }
        else if (temp <= 26 && temp >= 10)
        {
            v[i] = (v[i-1] + v[i-2]) % 1000000;
        }
        else
        {
            v[i] = v[i - 1] % 1000000;
        }
    }

    cout << v[size - 1];

    return 0;
}

첫 시점에서는 앞에 숫자가 존재하지 않기 때문에 별도로 처리가 필요합니다.

 

0처리를 신경쓰지 않는다면 실수하기 쉬운 느낌입니다.