题解:学而思编程 单词解密

【题目来源】

学而思编程:单词解密

【题目描述】

小猴发明了一套对字母的加密系统,其本质就是用字母在字典序中的编号来代替该字母,即用 \(1∼26\) 代替 \(a∼z\)

例如,单词 codec 是第 \(3\) 个字母,o 是第 \(15\) 个字母,d 是第 \(4\) 个字母,e 是第 \(5\) 个字母,因此 code 经过加密后,得到的密文为 \(31545\)

但是小猴发现,这样加密后的信息,可能会有多种解读,密文为 \(31545\) 除了 code 还可以是 caede,因此在解密时,有两种可能性。

现在,小猴给你一串密文,请你帮助小猴计算出所有可能的明文的种数对 \(10^9+7\) 取模。

【输入】

输入共一行,一串数字表示密文,保证一定有解。

【输出】

输出共一行,一个正整数表示答案。

【输入样例】

31545

【输出样例】

2

【代码详解】

#include<iostream>
#include<algorithm>
using namespace std;

const int MOD = 1e9 + 7;  // 模数
string s;  // 输入的数字字符串
int n, dp[100005];  // n: 字符串长度,dp: 动态规划数组

int main()
{
    cin >> s;  // 读入数字字符串
    n = s.size();  // 获取字符串长度
    s = ' ' + s;  // 在字符串前加一个空格,使下标从1开始
    
    dp[0] = dp[1] = 1;  // 初始化动态规划数组
    // dp[0] = 1: 空字符串有1种解码方式
    // dp[1] = 1: 第一个字符单独解码有1种方式(假设不是'0')
    
    for (int i = 2; i <= n; i++)
    {
        if (s[i] == '0')  // 如果当前字符是'0'
        {
            // 如果当前字符是'0',它必须和前一个字符组合
            // 且前一个字符只能是'1'或'2',否则无法解码
            // 解码方式数等于dp[i-2]
            dp[i] = dp[i - 2];
        }
        else if (s[i - 1] == '1' || s[i - 1] == '2' && s[i] <= '6')
        {
            // 如果前两个字符能组成10-26(除了20),则有两种解码方式:
            // 1. 当前字符单独解码:dp[i-1]种方式
            // 2. 前两个字符一起解码:dp[i-2]种方式
            dp[i] = (dp[i - 1] + dp[i - 2]) % MOD;
        }
        else
        {
            // 如果前两个字符不能组成有效数字,则当前字符必须单独解码
            dp[i] = dp[i - 1];
        }
        // cout<<dp[i]<<' ';  // 调试输出
    }
    
    cout << dp[n];  // 输出整个字符串的解码方式总数
    return 0;
}

【运行结果】

31545
2
posted @ 2026-02-21 15:07  团爸讲算法  阅读(6)  评论(0)    收藏  举报