解题思路

这是一个字典序生成问题。关键点如下:

  1. 字典中的每个单词都包含 个 'a' 和 个 'z'
  2. 所有单词按字典序排列
  3. 需要找出第 个单词

解题思路:

  1. 使用组合数学的思想
  2. 对于每个位置,我们需要决定放'a'还是'z'
  3. 如果在当前位置放'a',剩余字符的组合数如果大于等于 ,则放'a'
  4. 否则放'z',并将 减去放'a'时的组合数
  5. 最后检查 是否为1,不为1说明 超出了可能的组合数

代码

#include <iostream>
using namespace std;
typedef long long LL;

int main() {
    int n, m, k;
    cin >> n >> m >> k;
    
    string result;
    while (n && m) {
        // 计算当前位置放a时的组合数
        LL combinations = 1;
        for (int i = 1; i < n; i++) {
            combinations *= (n + m - i);
            combinations /= i;
            if (combinations > k) break;
        }
        
        if (combinations >= k) {
            result += 'a';
            n--;
        } else {
            result += 'z';
            m--;
            k -= combinations;
        }
    }
    
    // 检查是否有解
    if (k != 1) {
        cout << -1 << endl;
        return 0;
    }
    
    // 添加剩余的字符
    result += string(n, 'a') + string(m, 'z');
    cout << result << endl;
    
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int k = sc.nextInt();
        
        StringBuilder result = new StringBuilder();
        while (n > 0 && m > 0) {
            // 计算当前位置放a时的组合数
            long combinations = 1;
            for (int i = 1; i < n; i++) {
                combinations *= (n + m - i);
                combinations /= i;
                if (combinations > k) break;
            }
            
            if (combinations >= k) {
                result.append('a');
                n--;
            } else {
                result.append('z');
                m--;
                k -= combinations;
            }
        }
        
        // 检查是否有解
        if (k != 1) {
            System.out.println(-1);
            return;
        }
        
        // 添加剩余的字符
        for (int i = 0; i < n; i++) {
            result.append('a');
        }
        for (int i = 0; i < m; i++) {
            result.append('z');
        }
        System.out.println(result);
    }
}
def solve(n, m, k):
    result = []
    
    while n and m:
        # 计算当前位置放a时的组合数
        combinations = 1
        for i in range(1, n):
            combinations *= (n + m - i)
            combinations //= i
            if combinations > k:
                break
        
        if combinations >= k:
            result.append('a')
            n -= 1
        else:
            result.append('z')
            m -= 1
            k -= combinations
    
    # 检查是否有解
    if k != 1:
        return "-1"
    
    # 添加剩余的字符
    result.extend(['a'] * n)
    result.extend(['z'] * m)
    return ''.join(result)

n, m, k = map(int, input().split())
print(solve(n, m, k))

算法及复杂度

  • 算法:组合数学 + 贪心
  • 时间复杂度: - 每个位置最多计算一次组合数
  • 空间复杂度: - 需要存储结果字符串