解题思路

这是一道字符串字典序计数问题,主要思路如下:

  1. 问题分析:

    • 求字典序在 之间,长度在 之间的字符串个数
    • 字符串只包含小写字母(a-z)
    • 结果需要对 取模
  2. 解决方案:

    • 分别计算大于s1和大于s2的字符串个数,两者相减得到结果
    • 对于每个长度,计算满足条件的字符串数量
    • 考虑两种情况:当前位置大于目标字符串,或等于目标字符串继续比较
  3. 关键点:

    • 处理不同长度的字符串
    • 使用幂运算计算可能的组合数
    • 注意取模运算

代码

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

const int MOD = 1000007;

// 计算大于给定字符串的字符串个数
int getCount(string str, int len1, int len2) {
    int count = 0;
    int strLen = str.length();
    
    // 遍历所有可能的长度
    for (int len = len1; len <= len2; len++) {
        // 遍历字符串的每个位置
        for (int i = 0; i < strLen && i < len; i++) {
            // 计算当前位置可能的字符数
            long long temp = (26 - (str[i] - 'a' + 1));
            // 计算后续位置的组合数
            for (int j = 0; j < strLen - i - 1; j++) {
                temp = (temp * 26) % MOD;
            }
            count = (count + temp) % MOD;
        }
        
        // 处理长度大于原字符串的情况
        if (len > strLen) {
            long long temp = 1;
            for (int i = 0; i < len - strLen; i++) {
                temp = (temp * 26) % MOD;
            }
            count = (count + temp) % MOD;
        }
    }
    return count;
}

int main() {
    string s1, s2;
    int len1, len2;
    
    while (cin >> s1 >> s2 >> len1 >> len2) {
        int count1 = getCount(s1, len1, len2);
        int count2 = getCount(s2, len1, len2);
        int result = (count1 - count2 - 1 + MOD) % MOD;
        cout << result << endl;
    }
    return 0;
}
import java.util.*;

public class Main {
    private static final int MOD = 1000007;
    
    // 计算大于给定字符串的字符串个数
    private static int getCount(String str, int len1, int len2) {
        int count = 0;
        int strLen = str.length();
        
        // 遍历所有可能的长度
        for (int len = len1; len <= len2; len++) {
            // 遍历字符串的每个位置
            for (int i = 0; i < strLen && i < len; i++) {
                // 计算当前位置可能的字符数
                long temp = (26 - (str.charAt(i) - 'a' + 1));
                // 计算后续位置的组合数
                for (int j = 0; j < strLen - i - 1; j++) {
                    temp = (temp * 26) % MOD;
                }
                count = (int)((count + temp) % MOD);
            }
            
            // 处理长度大于原字符串的情况
            if (len > strLen) {
                long temp = 1;
                for (int i = 0; i < len - strLen; i++) {
                    temp = (temp * 26) % MOD;
                }
                count = (int)((count + temp) % MOD);
            }
        }
        return count;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s1 = sc.next();
            String s2 = sc.next();
            int len1 = sc.nextInt();
            int len2 = sc.nextInt();
            
            int count1 = getCount(s1, len1, len2);
            int count2 = getCount(s2, len1, len2);
            int result = ((count1 - count2 - 1) % MOD + MOD) % MOD;
            System.out.println(result);
        }
    }
}
MOD = 1000007

def get_count(s: str, len1: int, len2: int) -> int:
    count = 0
    str_len = len(s)
    
    # 遍历所有可能的长度
    for length in range(len1, len2 + 1):
        # 遍历字符串的每个位置
        for i in range(min(str_len, length)):
            # 计算当前位置可能的字符数
            temp = 26 - (ord(s[i]) - ord('a') + 1)
            # 计算后续位置的组合数
            for j in range(str_len - i - 1):
                temp = (temp * 26) % MOD
            count = (count + temp) % MOD
        
        # 处理长度大于原字符串的情况
        if length > str_len:
            temp = pow(26, length - str_len, MOD)
            count = (count + temp) % MOD
            
    return count

while True:
    try:
        s1, s2, len1, len2 = input().split()
        len1, len2 = int(len1), int(len2)
        
        count1 = get_count(s1, len1, len2)
        count2 = get_count(s2, len1, len2)
        result = ((count1 - count2 - 1) % MOD + MOD) % MOD
        print(result)
    except EOFError:
        break

算法及复杂度

  • 算法:数学计数
  • 时间复杂度: - 为长度范围, 为字符串长度
  • 空间复杂度: - 只需要常数额外空间