2019秋招-小红书编程题1
本题本源leetcode39题,只不过要处理输入: 10 [2,3,5] 输出 4 (说明满足条件的组合数有4个,分别是[2,2,2,2,2] ,[2,3,5],[5,5],[2,2,3,3])
题目描述:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
c++代码:
#include<iostream>
#include<cstdio>
#include<sstream>
#include<string>
#include<set>
#include<algorithm>
#include<vector>
using namespace std;
std::vector<std::string> split(const std::string& s, char delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
set<multiset<int>> store;//结果去重
void dfs(vector<int> &cand, int curr, multiset<int> res) {
if (curr == 0)
store.insert(res);
for (int i = 0; i < cand.size() && cand[i]<=curr; i++) {//剪枝
res.insert(cand[i]);//加枝
dfs(cand, curr - cand[i], res);//递归
res.erase(res.find(cand[i]));//回溯
}
return;
}
vector<vector<int>> findCom(vector<int> &cand,int target) {
vector<vector<int> > res;
sort(cand.begin(), cand.end());//剪枝
dfs(cand, target, multiset<int>{});//递归+回溯+剪枝
for (auto it : store) {
vector<int> tmp;
for (auto val : it)
tmp.push_back(val);
res.push_back(tmp);
}
return res;
}
int main() {
string line,str;
int sum;
while (getline(cin, line)) {
stringstream ss(line);
ss >> sum;
vector<string> tem;
vector<int> prices;
vector<vector<int>> ans;
int price;
while (ss >> str) {
string tar;
for (int i = 0; i < str.size(); i++) {
if (str[i] == '[')
tar = str.substr(i + 1, str.size() - 1);
break;
}
tem = split(tar,',');
}
for (int i = 0; i < tem.size(); i++) {
stringstream st(tem[i]);
st >> price;
prices.push_back(price);
}
ans = findCom(prices, sum);
cout << ans.size() << endl;
}
return 0;
}
结果: