C++ Which Number Doesn't Belong? - c++

I'm kind of a beginner with programming, but while writing a program of my own, I ran into a roadblock that I can't seem to get around.
Anyway, given a set of numbers like these in an array:
4
14
24
27
34
You can see how all of the numbers except one have a 4 in the ones place. How would I write a function that can return the number that is different in the ones place, 27 in this case? The numbers would be different every time the program is run, but due to the scenario, 4 of them will always have the same digit in the ones place. They wouldn't necessarily be in numerical order.
I couldn't seem to find a way to do it mathematically, nor was I able to find anything through search. Any ideas?

Jerry Coffin's solution is unnecessarily O(log N); it can be improved by using std::partition rather than std::sort:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> n = {4, 14, 27, 24, 34};
int first = n[0]%10;
std::partition(std::next(std::begin(n)), std::end(n),
[&](int a) { return first == a%10;});
std::cout << ((first != n[1]%10) ? n.front() : n.back());
}
But that still does way too many comparisons. The problem can be solved with at most (N+1)/2 comparisons:
#include <iostream>
#include <vector>
int odd_man_out(const std::vector<int> n) {
size_t i;
for (i = 0; i + 2 < n.size(); i += 2) {
if (n[i]%10 != n[i+1]%10)
return n[i]%10 != n[i+2]%10 ? i : i + 1;
}
if (i + 2 == n.size() && n[i]%10 == n[i-1]%10)
return i + 1;
else
return i;
}
int main() {
std::vector<int> n = {4, 14, 27, 24, 34};
std::cout << n[odd_man_out(n)];
}

Here's one way to do the job. Definitely not the most efficient possible, but kind of nice anyway. This one will work for any number of inputs, as long as only one is different from the rest (in the units digit, obviously).
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> n = {4, 14, 27, 24, 34};
std::sort(std::begin(n), std::end(n),
[](int a, int b) { return a%10 < b%10;});
std::cout << ((n[0]%10 < n[1]%10) ? n.front() : n.back());
}
Edit: I decided to add another. While this still does more comparisons than #Rici's (very nice) solution, it's at least linear (and doesn't rearrange the original data):
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> n = {4, 14, 27, 24, 34};
auto pos = std::adjacent_find(std::begin(n), std::end(n),
[](int a, int b) { return a%10 != b%10; });
if (pos != std::begin(n))
std::cout << pos[1];
else
std::cout << n[n[1]%10 != n[2]%10];
}

Write a program using % operator to take the unit place value
void check ()
{
int i, changeIndex =0;
for ( i = 0; i < 5; i++)
{
for (int k = 0; k < 5; k++)
{
if (a[i]%10 == a[k]%10)
{
changeIndex++;
}
}
if (changeIndex != 4)
{
break;
}
changeIndex = 0;
}
cout<<a[i];
}
This will work for a count of 5 and if only one of the numbers have a different unit place value

here you go... :p
works for any number of inputs... and even detects if they're all the same.
#include <iostream>
int main() {
int a[] = {4,14,24,34,27,94};
// assume a has more than 2 elements, otherwise, it makes no sense
unsigned ri = 0;
if (a[1]%10 == a[0]%10) {
for (ri = 2; (ri < sizeof(a)/sizeof(a[0])) && (a[ri]%10 == a[0]%10); ri++);
} else if (a[2]%10 == a[0]%10)
ri = 1;
if (ri < sizeof(a)/sizeof(a[0]))
std::cout << "weird number is a["<< ri <<"] = "<<a[ri] << std::endl;
else
std::cout<<"they're all the same" << std::endl;
return 0;
}
Notice that the actual work:
if (a[1]%10 == a[0]%10) {
for (ri = 2; (ri < sizeof(a)/sizeof(a[0])) && (a[ri]%10 == a[0]%10); ri++);
} else if (a[2]%10 == a[0]%10)
ri = 1;
is only 4 lines long! :p
check it out on liveworkspace
The run time is max(1,[location of the exception #]), which is O(n) where n is the size of a.

Related

Efficiently find the nth number in a series where the numbers are only divisible by 2,3 and 5

I want to find the nth number in a series of numbers only divisible by 2, 3 and 5 and not divisible by any other primes.
Here is the simplest solution that I have for finding the 1500th number. This takes about 16 seconds to execute. I want to know if there is a way to make it any faster like maybe using multi threading.
#include <iostream>
using namespace std;
int main()
{
int temp, seriesCounter = 1, currentNumber = 2;
while (seriesCounter < 1500)
{
temp = currentNumber;
//Remove all multiple of 2
while (temp % 2 == 0)
{
temp /= 2;
}
//Remove all multiple of 3
while (temp % 3 == 0)
{
temp /= 3;
}
//Remove all multiple of 5
while (temp % 5 == 0)
{
temp /= 5;
}
// If only 1 remains, the number is valid, else not.
if (temp == 1)
{
seriesCounter++;
}
currentNumber++;
}
cout << "The 1500th number in the series is : " << --currentNumber << endl << endl;
return 1;
}
Here's one pretty straightforward approach. It finds 1500th element in under a second (I didn't bother to measure more precisely).
#include <set>
#include <iostream>
int main() {
int n = 1500;
std::set<long long> s;
s.insert(2);
s.insert(3);
s.insert(5);
long long num = 0;
while (n--) {
num = *s.begin();
s.erase(s.begin());
s.insert(num*2);
s.insert(num*3);
s.insert(num*5);
}
std::cout << num;
}
Fast solution done in 0.000031s on a i7 laptop (result: num[1499]=860934420):
Time complexity is O(n) (n=1500 in your case). assume the current sequence is num[]. we want to grow it to 1500 elements. the main idea is to keep a record of three locations in the sequence num[], let's call them idx[0], idx[1] and idx[3]. so that 2num[idx[0]], 3num[idx[1]], and 5*num[idx[2]] becomes just >= the last number in sequence(num.back()). then add the smallest of the three to the end of the sequence (which becomes the new num.back()).
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
using std::vector;
using namespace std::chrono;
int main()
{
auto start = high_resolution_clock::now();
const vector<int> p{ 2,3,5 };
vector<int> idx{ 0,0,0 };
vector<int> num = { 2,3,4,5 }; num.reserve(1500);
vector<int> candidate(3);
while (num.size() < 1500) {
int candidate = INT_MAX;
for (int i = 0; i < p.size(); i++) {
int t;
while (num.back() >= (t=num[idx[i]] * p[i])) idx[i]++;
candidate = std::min(candidate, t);
}
num.push_back(candidate);
}
auto stop = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(stop - start);
std::cout << num.back();
std::cout <<"\ntakes "<< duration.count() << " microseconds";
}
The code can further be improved. The idea is the same, but the number of multiplication performed is reduced, by remembering the multiplication result in array candidate[3]:
const vector<int> p{ 2,3,5 };
vector<int> idx{ 1,0,0 };
vector<int> num = { 2,3,4,5 }; num.reserve(1500);
vector<int> candidate{ 6,6,10 };
while (num.size() < 1500) {
auto it = std::min_element(candidate.begin(), candidate.end());
if (num.back() != *it) num.push_back(*it);
int which_p = it - candidate.begin();
*it = num[++idx[which_p]] * p[which_p];
}

Comparing returned vectors from recursion tree branches

Suppose I have a given sum, say sum = 4. I am also given a vector = {2,4}. There are two ways to generate the given sum from the given vector (elements may be reused).
One way is just {4} cause 4 = 4.
Second way is {2,2} cause 2 + 2 = 4.
I have to find the shortest possible combination, therefore in this particular case the answer is {4}.
Here is my approach - I go through the tree, and when on the leaf I get a 0, we hit the base case, return {} vector, and fill up the vector while traversing the tree. When I get to a node, I choose the smaller of the two (or more) vectors. This way when I reach the root node, I should get a vector of the shortest combination that can yield me the target sum.
As of yet, I do not care about time constraints as such, I know there's a lot of repetitive computing going on so I will have to memoize it once I can get the basic version correct.
I have been trying to figure why this code is not working. Any insight would be appreciated.
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector<int> findBestSum(int targetSum, const vector<int> &elements, vector<vector<int>> &temp) {
if (targetSum == 0)
return {};
else if (targetSum < 0)
return {-1};
else {
vector<int> small;
for (auto &i : elements) {
int remainder = targetSum - i;
vector<int> returnedVector = findBestSum(remainder, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty()) {
returnedVector.push_back(i);
temp.push_back(returnedVector);
}
int smallestLength = temp[0].size();
for (auto &j : temp)
if (smallestLength >= j.size())
small = j;
}
return small;
}
}
int main() {
int targetSum = 6;
const vector<int> elements{2, 3, 5}; // answer should be [3,3] however I just get a 3...
vector<vector<int>> temp;
vector<int> bestSumVector = findBestSum(targetSum, elements, temp);
for (auto i : bestSumVector)
cout << i << " ";
}
Update (14th of July, 2021):
After a few busy months I have tried to lock horns with this problem and this time my code looks like this:
#include <iostream>
#include <vector>
#include <map>
#include <numeric>
using namespace std;
bool howSum(int &targetSum, vector<int> &elementVector, vector<int> &howSumVector, vector<vector<int>> &allSums) {
static int originaltargetsum = targetSum;
if (targetSum == 0)
return true;
else if (targetSum < 0)
return false;
else {
for (auto i : elementVector) {
int remainder = targetSum - i;
bool flag = howSum(remainder, elementVector, howSumVector, allSums);
if (flag) {
howSumVector.push_back(i);
if (targetSum == originaltargetsum ||
accumulate(howSumVector.begin(), howSumVector.end(), 0) == originaltargetsum) {
allSums.push_back(howSumVector);
howSumVector.clear();
}
return true;
}
}
return false;
}
}
int main() {
int sum = 8;
vector<int> elements = {1, 4, 5};
vector<vector<int>> allSums = {};
vector<int> workingBench = {};
howSum(sum, elements, workingBench, allSums);
for (auto &i : allSums) {
for (auto &j : i) {
cout << j << " ";
}
cout << endl;
}
}
For this I have sum as 8 and elements as {1, 4, 5}.
Also I'm storing and displaying all possible solutions right now (once that is correctly done, finding shortest vector and memoization should be easy). Possible solutions in this case are:
[1, 1, 1, 1, 1, 1, 1, 1]
[4, 4]
[5, 1, 1, 1]
[4, 1, 1, 1, 1]
Currently my code only shows the first possible combination. I'm pretty sure I'm returning true and false incorrectly, please help me out here.
I took a stab at this. I do have a working solution, hopefully it is what you want:
#include <iostream>
#include <vector>
#include <algorithm>
void howSum(int targetSum, const std::vector<int> & elementVector, const std::vector<int> & howSumVector, std::vector<std::vector<int>> & allSums)
{
static int originaltargetsum = targetSum;
if (targetSum == 0)
{
allSums.push_back(howSumVector);
return;
}
else if (targetSum < 0)
{
return;
}
else
{
for (const auto i : elementVector)
{
// an element less than or equal to 0 would cause an infinite loop
if (i <= 0)
continue;
std::vector<int> newSumVector = howSumVector;
newSumVector.push_back(i);
std::vector<int> newElementVector;
std::copy_if(std::begin(elementVector), std::end(elementVector), std::back_inserter(newElementVector), [i](int element){ return element >= i; });
howSum(targetSum - i, newElementVector, newSumVector, allSums);
}
}
}
int main()
{
int sum = 8;
std::vector<int> elements = { 1, 4, 5 };
std::vector<std::vector<int>> allSums = {};
std::vector<int> workingBench = {};
howSum(sum, elements, workingBench, allSums);
for (const auto & i : allSums)
{
for (const auto & j : i)
{
std::cout << j << " ";
}
std::cout << std::endl;
}
return 0;
}
I think, in general, you were over-thinking or over-engineering the problem. Like others have mentioned, your current code is returning true too early, and nothing besides the first element/combination is tested. With recursion, it is important to take care in your return cases - really, you only want a base case or two, and otherwise you want to recur.
With the solution I have here, the main thing I have added is copying the current combination of elements for each element you need to test. That solves your main issue of not testing every combination of numbers. In addition to that, it seemed better to append to allSums when the targetSum was reached. With those changes, I was able to do away with the bool return value and simplify the code a bit. Running the code above gives these solutions:
1 1 1 1 1 1 1 1
1 1 1 1 4
1 1 1 4 1
1 1 1 5
1 1 4 1 1
1 1 5 1
1 4 1 1 1
1 5 1 1
4 1 1 1 1
4 4
5 1 1 1
This does have some duplicates (because of the order things are tested) but I felt like it is good enough since you only want the smallest solution, 4 4. To find this, you would just need to sort the allSums vector by inner vector size and then take the first entry.
I think you need to change the implementation to correctly process elements of the vector.
In your implementation it doesn't go over all vector items, just the first one.
This is one way to do it if you use vector elements as the first parameter in your function.
vector<int> findBestSum(int element, int targetSum, const vector<int>& elements,
vector<vector<int>>& temp) {
if (targetSum == 0)
return {};
else if (targetSum < 0)
return { -1 };
else {
int remainder = targetSum - element;
vector<int> returnedVector = findBestSum(element, remainder, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty()) {
returnedVector.push_back(element);
return returnedVector;
}
return returnedVector;
}
}
int main() {
const int targetSum = 6;
const vector<int> elements{ 2, 3, 5 }; // answer should be [3,3] however I just get a 3...
vector<vector<int>> temp;
for (auto i : elements) {
vector<int> returnedVector = findBestSum(i, targetSum, elements, temp);
if ((!returnedVector.empty() && find(returnedVector.begin(), returnedVector.end(), -1) == returnedVector.end()) || returnedVector.empty())
temp.push_back(returnedVector);
}
if (temp.size() > 0) {
vector<int> bestSum = {};
size_t small = 0;
size_t smallestLength = temp[0].size();
for (auto& j : temp)
if (smallestLength >= j.size()) {
small = j.size();
bestSum = j;
}
for (auto i : bestSum)
cout << i << " ";
}
else
cout << " sum not found" << endl;
}

How can I indicate/print the distinct combinations to this Fibonacci number-based program?

I am constructing a function to determine how many distinct ways one can climb to the top of a staircase (can either climb 1 or 2 steps). Although I have gotten the main function to print out how many ways, I am confused on how to print the specific combinations i.e. There are three ways to climb to the top: (1, 1, 1), (1, 2), (2, 1).
#include <iostream>
using namespace std;
int climbStairs(int n);
int main()
{
int s = 4;
cout << "There are " << climbStairs(s) << " ways to climb to the top: ";
return 0;
}
int climbStairs(int n)
{
if(n == 0) return 0;
if(n == 1) return 1;
int one = 1;
int two = 0;
int result = 0;
for(int i = 1;i <= n;i++)
{
result = one + two;
two = one;
one = result;
}
return result;
}
Any explanation on how to go about printing the combinations will help, thank you so much!
Instead of having the variables one and two being integers, define them as sets of "paths". Then, do the same thing, except result is one with a 1 appended to all the "paths" in it plus two with a 2 appended to all the "paths" in it.
The algorithm looks something like this (I would recommend trying to do this yourself before looking at my code):
#include <set>
#include <string>
#include <iostream>
std::set<std::string> climbStairs(int n)
{
if(n == 0)
return {""};
if(n == 1)
return {"1"};
std::set<std::string> one({"1"}), two({""}), result;
for(int i = 2; i <= n; i++)
{
result.clear();
for(const std::string &path : one)
{
result.insert(path + '1');
}
for(const std::string &path : two)
{
result.insert(path + '2');
}
two = move(one);
one = move(result);
}
return one;
}
int main()
{
std::set<std::string> s = climbStairs(5);
for(const std::string &path : s)
{
std::cout << path << '\n';
}
}
This is the best way that I know of.

How to verify if given numbers from a file are in an arithmetic progression?

Basically what I want to do is to verify if the numbers : 180 30 80 280 130 330 230 30 30 330 80 are in an arithmetic progression and to find the ratio. I tried using the following algorithm but even if I insert 35 into the row (which is not correct) the answer is 50 instead of NO.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int x, fr[1000]={0} ,r=0 , ok=0, i, v[100], j=0;
ifstream f("bac.in");
while(f>>x)
fr[x]++;
for(i=0; i<1000; i++)
{
if(fr[i]!=0) // I search for the first frequency and only then start to count
ok=0;
else ok=1;
if(ok==0)
r++; // ratio
else {v[j++]=r; r=0;} // if another frequency was found, ratio is reseted
}
for(i=0;i<j-1;i++) // i verify if every ratio is equal in this for
{
if(v[i]==v[i+1])
ok=1;
else ok=0;
}
if(ok==1)
cout<<++v[i];
else cout<<"NO";
f.close();
}
My idea was to find the numbers of 0's between frequencies and to count that as the ratio and put it into an array where I would verifiy if the ratios are equal. If I missed any piece of information please tell me.
It has to be done in an efficient way, so putting the numbers into an array, sorting it, deleting the doubled numbers and only after that finding the ratio (if there is any) is out of the discussion.
You can use an std::set to accomplish this. Set guarantees no duplicates and also keeps your data sorted! This means you just have to toss everything into the set and then iterate over once to check the differences.
An insertion into the set costs you O(log(n)) and we're doing n of them so that'll be O(nlog(n)). Afterwards, we loop the set to check if we have a progression or not, so that'll be another O(n) giving us complexity O(nlog(n) + n) = O(nlog(n)). Is that fast enough for you?
#include <iostream>
#include <set>
#include <iterator>
int main() {
std::set<int> values;
int x;
while (std::cin >> x) { //replace cin with your file handler
values.insert(x);
}
int difference = 0;
bool good = true;
for(auto it = values.begin(); it != values.end() && std::next(it) != values.end(); it++) {
if(!difference) difference = *it - *std::next(it);
else if(difference != *it - *std::next(it)) good = false;
}
if(good) {
std::cout << "We have a progression!" << std::endl;
} else {
std::cout << "No go on the progression." << std::endl;
}
return 0;
}
See it in action here (ideone link).
Your error is in the last loop, which should be:
bool ok = true;
for (int i = 0; i < j - 1; ++i) // i verify if every ratio is equal in this for
{
if (v[i] != v[i+1]) {
ok = false;
break;
}
}
or
ok = (j == 0 || std::all_of(v, v + j, [&](int e) { return e == v[0]; }));
Fixed code:
std::vector<int> values {180, 30, 80, 280, 130, 330, 230, 30, 30, 330, 80 };
int fr[1000]={0};
for (auto e : values)
fr[e]++;
int j = 0;
int v[100];
int r = 0;
for(int i=0; i<1000; i++)
{
if(fr[i] == 0)
r++; // ratio
else {
v[j++]=r;
r=0;
} // if another frequency was found, ratio is reseted
}
bool ok = true;
for (int i = 1; i < j - 1; ++i) // i verify if every ratio is equal in this for
{
if (v[i] != v[i+1]) {
ok = false;
break;
}
}
if(ok==1)
std::cout << v[1] + 1;
else
std::cout<<"NO";
Demo.
Here is an O(n) solution:
It iterates over the list finding the smallest, second smallest and largest elements. (It does this with three seperate iterations, but it could be one loop with a little more code.)
Denoting these x0, x1, and xn, assuming there is an arithmetic progression we can now figure out the difference (c = x1 - x0) and total number of elements (n+1 = (xn - x0)/c).
We create an array of booleans of length n+1 and start marking off the present elements. If any don't fall into this pattern we immediately return false. At the end, we check that all the elements have been marked false.
By the way, I consider #scohe001's answer to be better. It is slightly slower, but it is more obvious that it is correct and that is what is really important, unless you have tried it and found that it really is too slow. If you're only dealing with a few hundred thousand elements or less, the time difference is unlikely to be noticable, especially if you're also having to read the elements from a file, which is likely to be much slower than this stage.
#include <iostream>
#include <vector>
#include <limits>
#include <boost/dynamic_bitset.hpp>
#include <algorithm>
#include <stdlib.h>
int conditionalMin(const std::vector<int>& numbers, int lowerBound)
{
int result = std::numeric_limits<int>::max();
for (int x : numbers) {
if (x < result && x > lowerBound) {
result = x;
}
}
return result;
}
bool isArithmeticSet(const std::vector<int>& numbers)
{
// Look for smallest, second smallest, and largest numbers
int x0 = *std::min_element(numbers.begin(), numbers.end());
int x1 = conditionalMin(numbers, x0);
int xn = *std::max_element(numbers.begin(), numbers.end());
// Find which elements are present (exit early if any inappropriate elements)
int sequenceCount = (xn - x0) / (x1 - x0) + 1;
boost::dynamic_bitset<> present(sequenceCount);
for (int x : numbers) {
div_t divResult = div(x - x0, x1 - x0);
if (divResult.rem != 0 || divResult.quot < 0 || divResult.quot > sequenceCount) {
return false;
}
present[divResult.quot] = true;
}
// Are all the required elements present?
return present.all();
}
int main() {
std::vector<int> numbers = {180, 30, 80, 280, 130, 330, 230, 30, 30, 330, 80 };
std::cout << "is an arithmetic set: " << isArithmeticSet(numbers) << "\n";
return 0;
}

Solving Subset algorithm using a recursive way gives wrong answer

I have tried to solve the following problem but I still get wrong answer, however the two test cases in the problem are correct answer for me.
Problem Statement: Subsets Sum, or "SS" (double S) for shortcut, is a classical problem in computer science.
We are given a set of positive integer numbers; we have to know if there is a non-empty subset of this set that the sum of its elements is equal to a given number.
Ex: suppose the set is [3, 4, 7, 9, 10] and the target number is 20 The sum of elements of the subset [3, 7, 10] is equal to 20.
Input Format: The input consists of many test cases, each test case is composed of two lines. On the first line of the input file there is a number indicates the number of test cases. The first line of each test case has two integer numbers (k, n): k is the target number, n <= 10 is the number of elements of the set. On the second line there are n integer numbers, each of these numbers is less than one hundred.
Output Format: for each test case print "YES" without quotes if there is a subset that satisfies the condition above, "NO" otherwise.
Sample Input:
2
1 5
45 26 36 4 8
49 8
49 9 5 37 0 42 15 19
Sample Output:
NO
YES
You can test the submission here: http://www.a2oj.com/p.jsp?ID=151
My Code:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
bool check = false;
void get(vector<int> arr, long total, int i, int k)
{
int length = arr.size() - 1;
if (i == length*length || i == length)
return;
if (total == k)
{
check = true;
return;
}
if (total >= k && i <= 1)
{
check = false;
return;
}
get(arr, total + arr[i], i + 1, k);
get(arr, total, i + 1, k);
}
int main(void) {
int t;
cin >> t;
vector<int> arr;
while (t--)
{
arr.clear();
int n, k;
cin >> n >> k;
for (int i = 0; i < k; i++)
{
int n;
cin >> n;
arr.push_back(n);
}
get(arr, 0, 0, n);
// arr = { 49,9,5,37,0,42,15,19 };
// get(arr, 0, 0, 49);
if (check)
cout << "YES" << endl;
else
cout << "NO" << endl;
check = false;
}
return 0;
}
I would do that way:
bool SS(const std::vector<int>& v, int total)
{
std::set<int> sums;
for (auto e : v) {
std::set<int> r = sums;
r.insert(e);
for (auto s : sums) {
r.insert(s + e);
}
sums.swap(r);
}
return sums.count(total);
}
where the std::set sums content is all the possible sums from the given vector.
Live example
In the last line of your get function, you are overwriting the value computed by the previous recursive call.
get(arr, total + arr[i], i + 1, k);
get(arr, total, i + 1, k);
So if the first call sets check to true and the second one sets it to false, you will lose first one. This is one of the reasons using global variables is considered harmful, specially in recursive functions.
Instead of defining a global variable, you should change your get function to return a boolean value, and then you can have your recursive like this:
return get(arr, total + arr[i], i + 1, k) || get(arr, total, i + 1, k);
Also try to use more meaningful variable/function names. For example your recursive function can have the following prototype:
bool addsUp(vector<int> array, int total, int from, int length);
As for your k and n variables in the main function, I think you should swap their names to comply with the problem statement (k is the desired total, n is the count of numbers).
And finally your boundary conditions seem to be not quite right. This is the recursive function that got accepted for me:
bool addsUp(vector<int> arr, long soFar, int from, int total) {
if (total == 0)
return false;
if (soFar == total)
return true;
if (soFar > total)
return false;
if (from >= arr.size())
return false;
return addsUp(arr, soFar + arr[from], from + 1, total) || addsUp(arr, soFar, from + 1, total);
}
I have a recursive code which you could have a try,
#include <iostream>
#include <vector>
bool find_subset(const std::vector<int>& input_data, int N, int target_value)
{
if (N == 1)
return input_data[0] == target_value;
bool result = false;
for (int i = 0; i < N; ++i)
{
std::vector<int> copy = input_data;
copy.erase(copy.begin() + i);
if (input_data[i] == target_value || find_subset(copy, N - 1, target_value - input_data[i]))
{
result = true;
break;
}
}
return result;
}
int main()
{
std::vector<int> test_1{45, 26, 36, 4, 8}; int target_1 = 1;
std::vector<int> test_2{49, 9, 5, 37, 0, 42, 15, 19}; int target_2 = 49;
std::vector<int> test_3{ 1, 3, 5, 7 }; int target_3 = 13;
std::vector<int> test_4{ 1, 3, 5, 7 }; int target_4 = 14;
std::cout << (find_subset(test_1, test_1.size(), target_1) ? "Yes" : "No") << std::endl;
std::cout << (find_subset(test_2, test_2.size(), target_2) ? "Yes" : "No") << std::endl;
std::cout << (find_subset(test_3, test_3.size(), target_3) ? "Yes" : "No") << std::endl;
std::cout << (find_subset(test_4, test_4.size(), target_4) ? "Yes" : "No") << std::endl;
return 0;
}
The output are:
No
Yes
Yes
No