1 条题解

  • 0
    @ 2025-4-10 1:07:38

    题意分析

    题目要求将严格按字母顺序递增的单词编码为整数。给定一个单词,需要:

    1. 检查是否为有效单词(字母严格递增)
    2. 如果是有效单词,计算其在所有可能有效单词字典序中的位置
    3. 无效单词输出00

    关键点:

    • 有效单词长度1len51 \leq len \leq 5
    • 字母必须满足str[i]>str[i1]str[i] > str[i-1]
    • 最大编码值为8368183681(对应vwxyzvwxyz

    解题思路

    1. 预处理组合数:使用动态规划计算组合数C(n,k)C(n,k)
    2. 验证单词有效性:检查字母是否严格递增
    3. 计算编码值
      • 累加所有长度小于当前单词长度的可能组合数
      • 对于相同长度的单词,逐位计算比当前单词小的组合数
    4. 输出结果:有效单词输出编码值,无效输出00

    实现步骤

    1. 初始化组合数表C[26][26]C[26][26]
    2. 读取输入单词
    3. 检查字母顺序有效性
    4. 计算:
      • 所有较短单词的数量:i=1len1C(26,i)\sum_{i=1}^{len-1}C(26,i)
      • 相同长度但字典序更小的单词数量
    5. 输出sum+1sum+1(当前单词的位置)

    C++实现

    #include <iostream>
    #include <string.h>
    using namespace std;
    
    int C[50][50]; // 组合数表
    
    void initTable() {
        // 计算组合数 C(n,k) = C(n-1,k-1) + C(n-1,k)
        for(int i=0;i<=26;i++) {
            for(int j=0;j<=i;j++) {
                if(j==0 || i==j)
                    C[i][j]=1;
                else
                    C[i][j]=C[i-1][j-1]+C[i-1][j];
            }
        }
        C[0][0]=0; // 边界条件处理
    }
    
    int main() {
        initTable();
        char str[50];
    
        while(cin>>str) {
            int sum=0;
            int len=strlen(str);
            
            // 检查字母顺序
            bool isValid=true;
            for(int i=1;i<len;i++) {
                if(str[i]<=str[i-1]) {
                    cout<<0<<endl;
                    isValid=false;
                    break;
                }
            }
            if(!isValid) continue;
    
            // 计算较短单词数量
            for(int i=1;i<len;i++)
                sum += C[26][i];
    
            // 计算相同长度但更小的单词
            for(int i=0;i<len;i++) {
                char c = (i==0) ? 'a' : str[i-1]+1;
                while(c<str[i]) {
                    sum += C['z'-c][len-1-i];
                    c++;
                }
            }
    
            cout<<sum+1<<endl;
        }
        return 0;
    }
    

    代码说明

    1. 组合数预处理

      • 使用递推公式C(n,k)=C(n1,k1)+C(n1,k)C(n,k)=C(n-1,k-1)+C(n-1,k)计算
      • 初始化C[26][26]C[26][26]的表
    2. 输入处理

      • 读取字符串并检查长度
      • 验证字母严格递增
    3. 编码计算

      • 较短单词数:C(26,i)\sum C(26,i)
      • 相同长度更小单词数:逐位比较计算组合数
    4. 输出

      • 有效单词:sum+1sum+1
      • 无效单词:00
    5. 复杂度分析

      • 预处理:O(262)O(26^2)
      • 查询处理:O(len2)O(len^2)
      • 总复杂度:O(262+nlen2)O(26^2 + n \cdot len^2)nn为查询次数
    • 1

    信息

    ID
    497
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者