All possible sum from a given of coins - c++

You have n coins with certain values. Your task is to find all the money sums you can create using these coins.
Input
The first input line has an integer n: the number of coins.
The next line has n integers x1,x2,…,xn: the values of the coins.
Output
First print an integer k: the number of distinct money sums. After this, print all possible sums in increasing order.
Constraints
1≤n≤100
1≤xi≤1000
Example
Input:
4
4 2 5 2
Output:
9
2 4 5 6 7 8 9 11 13
I have written a code which works perfectly for the small inputs but gives the wrong answer to the large inputs. Please help to find the mistake and how do I correct it.
my code is:
#include <bits/stdc++.h>
using namespace std;
set<long long> s;
// Prints sums of all subsets of array
void subsetSums(long long arr[], long long n)
{
// There are totoal 2^n subsets
long long total = 1 << n;
// Consider all numbers from 0 to 2^n - 1
for (long long i = 0; i < total; i++)
{
long long sum = 0;
// Consider binary reprsentation of
// current i to decide which elements
// to pick.
for (long long j = 0; j < n; j++)
if (i & (1 << j))
sum += arr[j];
// Print sum of picked elements.
if (sum)
s.insert(sum);
}
}
// Driver code
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
long long n;
cin >> n;
long long arr[n];
for (long long i = 0; i < n; i++)
{
cin >> arr[i];
}
subsetSums(arr, n);
cout << s.size() << "\n";
for (auto it = s.begin(); it != s.end(); ++it)
cout << *it << " ";
return 0;
}
for example, it gives the wrong answer for
50
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
as
18
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36
the correct output should be:
50
1 2 3 4 ... 50

your code is simply too slow 2^n subsets gives ‭1,267,650,600,228,229,401,496,703,205,376‬ subsets in the worst case (when n=100) while C++ does on average about 1000,000,000 operations per second.
This problem can be solved with dynamic programming, consider having an array dp of size 100001, so that dp[x] denotes if sum of x is possible to achieve.
Base case is easy - sum of 0 is possible without using any coins: dp[0]=1
Then for each coin we can try to increase existing sums by coins value to fill up our table:
for each coinValue:
for coinSum = 100000 - coinValue; coinSum >=0; coinSum--)
if(dp[coinSum])
dp[coinSum + coinValue]=1
Notice that we are looping backwards, this is done on purpose so that each coin gets used only once.
Complexity: O(n^2*maxCoinValue)

Your algorithm is poor, but the reason you're getting wrong results is because you're overflowing int. long long total = 1<<n; shifts an int left by n places, and the fact you're assigning the result to a long long is irrelevant.
You can find problems like this using ubsan. Here's a reproduction of your problem, including warning messages from ubsan:
$ clang++ -fsanitize=undefined a.cpp -o a && ./a
50
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
a.cpp:11:25: runtime error: shift exponent 50 is too large for 32-bit type 'int'
a.cpp:22:24: runtime error: shift exponent 32 is too large for 32-bit type 'int'
18
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36

Related

How can I find the prime numbers?

How can I find the prime numbers in a one-dimensional array in C++ in a simple way ??
{
int list[5];
int i,sum = 0;
for (i = 0; i < 5; i++)
{
cout << "Enter The List [" << i << "]: "; cin >> list[i];
sum = sum + list[i];
}
cout << endl;
cout << "The Sum Is:" << sum << endl;
}
Emphasizing on the comment of #john:
Create a function (say bool is_prime(int n)).
Now check if the number n is a prime or not.
So, you need to check if each of the positive integers more than 1 before n divides n or not without leaving any remainder. There's a shorter workaround, which will greatly reduce the computational cost. Just checking till the square root of the number n will do. Hence the function sqrt() is used.
So now, our is_prime() function is pretty easy to build as you can see:
bool is_prime(int n)
{
int i,p=0;
for(i=2;i<=sqrt(n);i++)
{
if(n%i==0)
{
p=1;
break; //even if one integer divides the number, then it is composite.
}
}
if(p==1)
return false; //The number is a composite.
else
return true; //The number is a prime.
}
Now, you just need to pass every value of the array into this function, and your job will be done.
Also, this program can be made even better if you check for the special case of 1 which is neither composite nor prime. A suggestion is, check your array element if it is 1 or not. If not, then pass the value in the function, else just print that it is a 1.
NOTE: The sqrt() function is available in the cmath library in C++ so you need to include that in your program too.
You can use sieve of Eratosthenes. Simply how it works is it iterates (from 2) through an boolean array and if arr[i] is prime (is true, i is the given number), sets every multiplicity to false.
Start with an array filled with true
Numbers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
is prime 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
first you have to set arr[0] and arr[1] to false, because these are not prime numbers
Numbers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
is prime 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Now, you go to 2 and set every multiplication of it to false.
in this case 4, 6, 8, 10, 12, 14 16...
Numbers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
is prime 0 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0
Then do it for 3
so 6, 9, 12, 15
Numbers 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
is prime 0 0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0
4 is not prime so you skip it
5 is prime so you do the same as for 2 and 3 (10 -> false, 15 -> false etc.)
after you use it, you can simply check if n is prime
if (arr[n] == true)
cout << n << " is prime";
else
cout << n << " is not prime";
you can find it easily on internet, for example here (there are some optimizations you can add, too)

0 < res <= (1 << 31) -1 - What does this mean?

This statement checks whether a number is 32 bits.
0 < res <= (1 << 31) -1
I can't seem to understand how, can someone help understand this bit shift syntax?
Well, lets begin with an example:
1 in binary is 1
2 in binary is 10
4 in binary is 100
We can see that we need to 'add' an 0 at the end of each number to multiply by 2 and in most language we can do this with this syntax: number << 1
Here we are saying that we add a 1 time a 0 to the left. number >> 1 and here we add 1 time a 0 to the right.
So 1 << 31 means 1 * 2 * 2 * 2 ... 31 times which means 2^31 (so 32 bits)

Optimize triplet summation in C++

Problem
I need to compute a function of an array of integers. For every three-element subset (or triplet) of the array, I need to compute the term floor((sum of triplet)/(product of triplet)). Then I need to return the sum of all such terms.
Example
Input (length; array):
5
1 2 1 7 3
Output:
6
Explanation
The following triplets exist in the given array:
1 2 1
1 2 7
1 2 3
1 1 7
1 1 3
1 7 3
2 1 7
2 1 3
2 7 3
1 7 3
Considering these triplets from the sample input:
1 2 1 contributes 2, because floor((1+2+1)/(1*2*1)) = floor(4/2) = 2
1 2 3 contributes 1
1 1 7 contributes 1
1 1 3 contributes 1
2 1 3 contributes 1
All other triplets contribute 0 to the sum.
Hence the answer is (2+1+1+1+1)=6.
My Solution
What I tried is complexity O(n^3). Code is given below:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long t,n[300005],sum=0,mul=1,i,j,k,res=0;
cin >> t;
for(i=0;i<t;i++)
cin >>n[i];
for(i=0;i<t-2;i++)
for(j=i+1;j<t-1;j++)
for(k=j+1;k<t;k++)
{
sum = n[i]+n[j]+n[k];
mul = n[i]*n[j]*n[k];
res += floor(sum/mul);
}
cout << res << endl;
return 0;
}
Is there any hint of better optimization?
While still O(n^3), you could save some operations by caching the redundant calculations between n[i] and n[j] as you iterate over n[k].
For example:
long sum_ij,mul_ij;
for(i=0;i<t-2;i++) {
for(j=i+1;j<t-1;j++) {
sum_ij = n[i]+n[j];
mul_ij = n[i]*n[j];
for(k=j+1;k<t;k++)
{
sum = sum_ij+n[k];
mul = mul_ij*n[k];
res += floor(sum/mul);
}
}
}

Error implementing Radix sort in C++

I’m trying to implement Radix-Sort with arrays of long int.
My Algorithm has 2 inputs:
The number ’n’ of elements to be sorted
The number ‘b’ of bits per digit (So, insted of taking the last decimal number, I take the groups of ‘b’ digits, representing one digit)
But, when I try to sort the vector, I find 2 problems:
First one: It doesn’t sort the vector properly
Second one: I have implemented it for taking from the last group of bits to the first one. But it seems like it tries to sort in in the opposite direction.
Here is the code:
#define MAX_BITS sizeof(long int)*8
#define VectorL vector<long int>
struct Compare
{
int beg = 0;
int bits_per_digit = 2;
Compare(int x, int y){
beg = x;
bits_per_digit = y;
}
bool operator() (long& a, long& b){
int _begin = beg;
int _final = _begin + bits_per_digit - 1;
assert(_begin <= _final); // b==f if bits_per_digit = 1;
bitset<sizeof(long int)> _x(a), _y(b);
for(_begin; _begin <= _final; _begin++)
if(_x[_begin] != _y[_begin])
return (_x[_begin] < _y[_begin]) ? true : false;
return false;
}
};
void ALG(VectorL& nums, int n, int b)
{
assert(nums.size() == n);
assert(MAX_BITS%b == 0);
int _grupos = MAX_BITS/b;
Compare myobject(MAX_BITS,b);
for (int g = 1; g <= _grupos; g++)
{
myobject.beg -= b;
sort(nums.begin(), nums.end(), myobject);
}
}
Here’s the main:
int n=5, b=2;
VectorL nums(n);
nums[0] = 2;
nums[1] = 6;
nums[2] = 1;
nums[3] = 5;
nums[4] = 0;
ALG(nums, n, b);
And here’s the output:
Initial Vector: 2 6 1 5 0
From bit 62 to bit 63
Vector after the 1º sort: 2 6 1 5 0
From bit 60 to bit 61
Vector after the 2º sort: 2 6 1 5 0
From bit 58 to bit 59
Vector after the 3º sort: 2 6 1 5 0
From bit 56 to bit 57
Vector after the 4º sort: 2 6 1 5 0
From bit 54 to bit 55
Vector after the 5º sort: 2 6 1 5 0
From bit 52 to bit 53
Vector after the 6º sort: 2 6 1 5 0
From bit 50 to bit 51
Vector after the 7º sort: 2 6 1 5 0
From bit 48 to bit 49
Vector after the 8º sort: 2 6 1 5 0
From bit 46 to bit 47
Vector after the 9º sort: 2 6 1 5 0
From bit 44 to bit 45
Vector after the 10º sort: 2 6 1 5 0
From bit 42 to bit 43
Vector after the 11º sort: 2 6 1 5 0
From bit 40 to bit 41
Vector after the 12º sort: 2 6 1 5 0
From bit 38 to bit 39
Vector after the 13º sort: 2 6 1 5 0
From bit 36 to bit 37
Vector after the 14º sort: 2 6 1 5 0
From bit 34 to bit 35
Vector after the 15º sort: 2 6 1 5 0
From bit 32 to bit 33
Vector after the 16º sort: 2 6 1 5 0
From bit 30 to bit 31
Vector after the 17º sort: 2 6 1 5 0
From bit 28 to bit 29
Vector after the 18º sort: 2 6 1 5 0
From bit 26 to bit 27
Vector after the 19º sort: 2 6 1 5 0
From bit 24 to bit 25
Vector after the 20º sort: 2 6 1 5 0
From bit 22 to bit 23
Vector after the 21º sort: 2 6 1 5 0
From bit 20 to bit 21
Vector after the 22º sort: 2 6 1 5 0
From bit 18 to bit 19
Vector after the 23º sort: 2 6 1 5 0
From bit 16 to bit 17
Vector after the 24º sort: 2 6 1 5 0
From bit 14 to bit 15
Vector after the 25º sort: 2 6 1 5 0
From bit 12 to bit 13
Vector after the 26º sort: 2 6 1 5 0
From bit 10 to bit 11
Vector after the 27º sort: 2 6 1 5 0
From bit 8 to bit 9
Vector after the 28º sort: 2 6 1 5 0
From bit 6 to bit 7
Vector after the 29º sort: 2 6 1 5 0
From bit 4 to bit 5
Vector after the 30º sort: 2 6 1 5 0
From bit 2 to bit 3
Vector after the 31º sort: 2 1 0 6 5
From bit 0 to bit 1
Vector after the 32º sort: 0 2 6 1 5
As you can see in the output, the changes only happens in the 31st and 32nd sort (so, that means the significant bits are found in the last searchs).
Anyone can help me to find my mistake?
Thanks in advance.

Recursion function -counting permuation and ignoring permutation

I am given this problem:
We are going over recursion in my class and I do not quite understand it, I was wondering if someone can help me with this problem
let c(n) be the number of different group integers that can be chosen from the integers 1 through n-1, so that the integers in each group add up to n (for example, n=4=[1+1+1+1]=[1+1+2]=[2+2]). Write a recursive definition for c(n) under the following variations:
a) You count permutations. For example, 1,2,1 and 1,1,2 are two groups that each add up to 4
b)you ignore permutations
I know permutations is how many ways you can arrange a set of numbers, so is my code below correct? I get an answer of 7?
Here is my code for part a:
int recurse (int n);
int main(){
int a=4;
int sum_perm;
sum_perm=recurse(a);
cout<<sum_perm-1<<endl;
//Can I do -1 here because it should be from a group of integers from 1 to n-1?
return 0;
}
int recurse(int n)
{
int sum = 1;
if (n == 1){
return 1;
}
for(int i = 1; i < n; i++){
sum += recurse(n - i);
}
return sum;
}
For part B, if I am not counting permutations, what am I counting?
Here is my code for part b:
int without (int n, int max);
int main(){
int a=4, b =3;
int sum_without;
sum_without=without(a,b);
cout<<sum_without<<endl;
system("Pause");
return 0;
}
int without(int n, int max)
{
if(n == 1 || max == 1){
return 1;
}
else if (n == max){
return 1 + without(n, n-1);
}
else{
return without(n,max-1) + without(n-max, max);
}
}
You don't show any code to generate the combinations of numbers that produce a sum. Link to wiki article about partitions .
In this case, the goal is to count the number of combinations and/or permutations, which might be possible without actually generating a set of combinations. Not sure if recursion helps here, but you can convert any loop into recursion if you pass enough variables.
Example "partitions"
1 combination that sums to 1:
1
2 combinations that sum to 2:
1 1
2
3 combinations that sum to 3:
1 1 1
1 2
3
5 combinations that sum to 4:
1 1 1 1
1 1 2
1 3
2 2
4
7 combinations that sum to 5:
1 1 1 1 1
1 1 1 2
1 1 3
1 2 2
1 4
2 3
5
11 combinations of numbers that sum to 6:
1 1 1 1 1 1
1 1 1 1 2
1 1 1 3
1 1 2 2
1 1 4
1 2 3
2 2 2
1 5
2 4
3 3
6
I would recommend combinations directly being considered. While it seems like the more difficult case a simple rule makes it trivial.
Numbers calculated are in decreasing order
This requires you to track the last number, but ensures you don't calculate 1 5 and then 5 1, as the former is impossible.