小易的字典--牛客网--面试题

题目描述

小易在学校中学习了关于字符串的理论, 于是他基于此完成了一个字典的项目。

小易的这个字典很奇特, 字典内的每个单词都包含n个'a'和m个'z', 并且所有单词按照字典序排列。

小易现在希望你能帮他找出第k个单词是什么。

输入描述:

 

输入包括一行三个整数n, m, k(1 <= n, m <= 100, 1 <= k <= 109), 以空格分割。

输出描述:

输出第k个字典中的字符串,如果无解,输出-1。

示例1

输入

2 2 6

输出

zzaa

说明

字典中的字符串依次为aazz azaz azza zaaz zaza zzaa

参考代码:

#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
    void solve(int n, int m, long long k) {
        vector<char> x;//
        while (n && m) {
            //每次迭代问题规模缩减一个单位
            排列组合:假设当前序列首字符为a,剩下n-1个a放在剩下n - 1 +m 个位置共有的可能数
            long long count = 1;
            for (int i = 0; i < n - 1; i++) {//求组合数
                count *= n - 1 + m - i;
                count /= (i + 1);
                if (count > k)break;//防止越界。count>k就可以退出计算了
            }
            if (k <= count) {//如果k小于等于count,则表明首字符的确应为a
                x.push_back('a');
                n--;//问题缩减为 n-1个a和m个z 中找第k大
            }
            else {
                x.push_back('z');
                m--;//问题缩减为 n-1个a和m个z 中找第k-count大
                k -= count;
            }
        }
        //循环结束后,剩余子序列只存在"aa..aaa" 或 "zz..zzz"1种情况
        if (k != 1) {//
            cout << -1;
            return;
        }
        while (n--)x.push_back('a');
        while (m--)x.push_back('z');
        for (int i = 0; i < x.size(); i++) {
            cout << x[i];
        }
    }
};
int main() {
    Solution a;
    int n, m;
    long long k;
    while (cin >> n >> m >> k) {
        a.solve(n, m, k);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40513792/article/details/104287962