【华为OD机试 】猜密码(C++ Java JavaScript Python)

422 阅读2分钟

题目描述

小杨申请了一个保密柜,但是他忘记了密码。只记得密码都是数字,而且所有数字都是不重复的。

请你根据他记住的数字范围和密码的最小数字数量,帮他算下有哪些可能的组合,规则如下
1、输出的组合都是从可选的数字范围中选取的,且不能重复;
2、输出的密码数字要按照从小到大的顺序排列,密码组合需要按照字母顺序,从小到大的顺序排序。
3、输出的每一个组合的数字的数量要大于等于密码最小数字数量;
4、如果可能的组合为空,则返回“None”

输入描述

1、输入的第一行是可能的密码数字列表,数字间以半角逗号分隔
2、输入的第二行是密码最小数字数量

输出描述

可能的密码组合,每种组合显示成一行,每个组合内部的数字以半角逗号分隔,从小到大的顺序排列。
输出的组合间需要按照字典序排序。
比如:
2,3,4放到2,4的前面

用例

输入2,3,4
2
输出2,3
2,3,4
2,4
3,4
说明

最小密码数量是两个,可能有三种组合:
2,3
2,4
3,4

三个密码有一种:
2,3,4

参考

华为OD机试备考攻略 以及题库目录分值说明 考点说明

C++

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void dfs(vector<string>& nums, int index, int level, vector<string>& path, vector<string>& res) {
    if (path.size() >= level) { // 当路径长度达到level时,记录路径
        string combination = "";
        for (int i = 0; i < path.size(); i++) {
            if (i > 0) combination += ","; // 数字之间用逗号分隔
            combination += path[i];
        }
        res.push_back(combination);
    }
    if (path.size() == nums.size()) return; // 路径长度达到nums长度时退出

    for (int i = index; i < nums.size(); i++) { // 枚举数字
        path.push_back(nums[i]);
        dfs(nums, i + 1, level, path, res); // 递归搜索
        path.pop_back();
    }
}

int main() {
    string line;
    getline(cin, line); // 读入数字列表
    int level;
    cin >> level; // 读入最小数字数量

    vector<string> nums;
    string delimiter = ",";
    size_t pos = 0;
    string token;
    while ((pos = line.find(delimiter)) != string::npos) { // 分割数字列表
        token = line.substr(0, pos);
        nums.push_back(token);
        line.erase(0, pos + delimiter.length());
    }
    nums.push_back(line);
    sort(nums.begin(), nums.end()); // 排序

    vector<string> res;
    vector<string> path;
    dfs(nums, 0, level, path, res);

    if (res.size()) {
        for (int i = 0; i < res.size(); i++) {
            cout << res[i] << endl;
        }
    } else {
        cout << "None" << endl;
    }

    return 0;
}