解题思路
这是一道字符串字典序计数问题,主要思路如下:
-
问题分析:
- 求字典序在
和
之间,长度在
到
之间的字符串个数
- 字符串只包含小写字母(a-z)
- 结果需要对
取模
- 求字典序在
-
解决方案:
- 分别计算大于s1和大于s2的字符串个数,两者相减得到结果
- 对于每个长度,计算满足条件的字符串数量
- 考虑两种情况:当前位置大于目标字符串,或等于目标字符串继续比较
-
关键点:
- 处理不同长度的字符串
- 使用幂运算计算可能的组合数
- 注意取模运算
代码
#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
算法及复杂度
- 算法:数学计数
- 时间复杂度:
-
为长度范围,
为字符串长度
- 空间复杂度:
- 只需要常数额外空间