贝壳2019秋招提前批算法笔试题目“丢失的卡片”

输入样例2:

2  12  9  3  3  3  3  2  2  2

输出样例2:

26  12

26  21

 思路:先确定N再确定X,从1开始统计到N的数字包含0~9的个数,直到找到第一个符合0~9的个数都不小于给定的统计值为止。找到N之后再找出X对应的数字(这个过程用到全排列leetcode47)

#include <iostream>
#include <sstream>
#include <vector>
#include <iomanip>
#include <queue> 
#include <iomanip>
using namespace std;

void help1(vector<int>& count, int n) {
    string str = to_string(n);
    for (int i = 0; i<str.size(); i++) {
        count[str[i] - '0']++;
    }
}

bool stop(vector<int>& num, vector<int>& count) {
    for (int i = 0; i<10; i++) {
        if (count[i] < num[i])
            return 0;
    }
    return 1;
}

void backtrack3(vector<int>& nums, vector<bool>& vis, int curSize, int& len,
    vector<int>& path, vector<vector<int> >& res) {
    if (curSize == len) {
        // 此时 path 已经保存了 nums 中的所有数字,已经成为了一个排列
        res.push_back(path);
        return;
    }
    for (int i = 0; i<len; i++) {
        if (!vis[i]) {
            //如果上一个元素刚遍历过,而且当前元素和上一个元素相同,那么说明可以剪枝;
            if (i>0 && nums[i] == nums[i - 1] && vis[i - 1]) continue;

            path.push_back(nums[i]);
            vis[i] = true;
            backtrack3(nums, vis, curSize + 1, len, path, res);
            // 刚开始接触回溯算法的时候常常会忽略状态重置
            // 回溯的时候,一定要记得状态重置
            path.pop_back();
            vis[i] = false;
        }
    }
}

vector<vector<int> > permuteUnique(vector<int>& nums) {
    vector<vector<int> > res;
    int len = nums.size();
    if (len == 0) return { {} };

    sort(nums.begin(), nums.end());

    vector<bool> vis(len, 0);
    vector<int> path;
    backtrack3(nums, vis, 0, len, path, res);

    return res;
}

bool input(vector<int>& num) { 
    int cur;
    bool sign = 0;
    if (cin >> cur) {
        sign = 1;
        num[0] = cur;
        for (int i = 1; i < 10; i++) {
            cin >> num[i];
        }
    } 
    return sign;
}

int main() { 
    vector<int> num(10);
    while ( input(num)  ) { 
        vector<int> count(10, 0);  //记录1~N 所有数字出现的次数 
        int tar = 1;
        while (1) {
            help1(count, tar);
            if (stop(num, count)) break;
            tar++;
        }

        vector<int > number;
        for (int i = 0; i<10; i++) {
            if (num[i] < count[i]) {
                for (int j = 0; j < count[i] - num[i]; j++) {
                    number.push_back(i);
                }
            }
        }

        vector<vector<int> > x_res = permuteUnique(number);   //leetcode47
        for (int i = 0; i<x_res.size(); i++) {
            if (x_res[i][0] == 0) continue;
            int x = 0;
            for (int j = 0; j<x_res[i].size(); j++) {
                x = x * 10 + x_res[i][j];
                if (x>tar) break;
            }
            if (x <= tar) {
                cout << tar << " " << x << endl;
            }
        }        
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/liugl7/p/11333665.html