I'm trying to build a recursive call for coin change in c++ . i tried most of the algorithm on the internet but it doesn't seem to apply with vector or it doesn't out the sums of the coin used. Can anyone help me understand what the recursive function has to call? So my algorithm doesn't give me the minimum number of coin used and i don't know how to save the coin used.
int coin(vector<int> denom, int s,int N)
{
if(N == 0)
{
return 1;
}
if(N < 0 || (N > 0 && s < 0))
{
return 0;
}
return min(coin(denom,s - 1, N), 1 + coin(denom, s,N-denom[s-1]));
}
Input a value N:
Input: 40
Input how many denominations:
Input: 3
Denominations #1:
Input: 5
Denominations #2:
Input: 20
Denominations #3:
Input: 30
Output:
Minimum # of coins: 2
Coin used: 20 + 20
Don't want: 30 + 5 + 5
Some points to consider:
Firstly, there is no need to send the number of denominations i.e. s
as an argument to the coin method as long as a vector is being used, because vector has inbuilt size() method which does that job for us.
Secondly, to save the solution you need another vector of int named solution, but this vector is just to keep a record and has nothing to do with the actual recursive implementation and hence, it is defined as a global variable. Alternatively, you could pass it as an argument by reference to the coin method too.
Thirdly, the denominations entered by the user should be sorted before passing them to the coin method. For this, I have used the sort method from the algorithm library.
What the recursive algorithm basically does is:
At each step, it considers the largest denomination d (last element in the sorted denomination vector denom like denom[denom.size() - 1]) which is then removed from the vector using pop_back method of vector.
Using d we find count_d, which is the number of coins of denomination d, used in the solution. We get this by simply applying a div operation like N/d, which gives the Quotient.
Then d is added to the vector solution, count_d number of times.
The recursive call, adds count_d from this iteration and recalls coin with the reduced denominations vector denom and Remainder of the amount N using N%d.
See Quotient and Remainder for clarity of what div / and mod % operators do.
Here is the code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> solution;
int coin(vector<int> denom, int N)
{
if(N <= 0 || denom.size() <= 0)
{
return 0;
}
int d = denom[denom.size() - 1];
denom.pop_back();
int count_d = N/d;
solution.insert(solution.end(), count_d, d);
return count_d + coin(denom, N%d);
}
int main()
{
int N,s;
cout<<"Input a value N:\nInput: ";
cin>>N;
cout<<"Input how many denominations:\nInput: ";
cin>>s;
vector<int> denom;
for(int i = 0; i < s; i++)
{
int d;
cout<<"Denominations #"<<i+1<<":\nInput: ";
cin>>d;
denom.push_back(d);
}
std::sort(denom.begin(), denom.end());
int minNoOfCoins = coin(denom, N);
cout<<"\nOutput:\nMinimum # of coins: "<<minNoOfCoins;
if(minNoOfCoins > 0)
{
cout<<"\nCoins used: ";
for(int i = 0; i < solution.size(); i++)
{
if(i > 0)
{
cout<<" + ";
}
cout<<solution[i];
}
}
cout<<endl;
system("pause");
}
Related
Given an array count the total number of pairs of (i,j) such that A[i]*A[j] is not a perfect square.
input
n=3
input array={2,3,12}
output:2
explanation 2 * 3 i.e A[0]*A[1] & 2 * 12 i.e A[0]*A[2] does form perfect square. pair 2 * 3 & 3 * 2 are counted as a single pair.
my approach & code:
i simply run 2 for loop which gives result in quardratic time. How can i optimise it.
#include <iostream>
#include<vector>
#include<cmath>
using namespace std;
bool isPerfectSquare(long long x)
{
if (x >= 0) {
long long sr = sqrt(x);
return (sr * sr == x);
}
return false;
}
int main() {
// your code goes here
long long t;cin>>t;
while(t--){
long long n;cin>>n;
vector<long long>v(n);
for(int i=0;i<n;i++){
cin>>v[i];
}
long long count=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(!isPerfectSquare(v[i]*v[j])){
count++;
}
}
}
cout<<count<<endl;
}
return 0;
}
The trick is to take out all the square factors first, which you can trivially do by testing divisibility by all numbers up to sqrt(A[i])). Then only matching pairs produce perfect square products:
[2,3,12] -> [2,3,3]
You can determine the number of square pairs by counting the frequency of each value, and then subtract that from the total number of pairs.
I have a program like this: given a sequence of integers, find the biggest prime and its positon.
Example:
input:
9 // how many numbers
19 7 81 33 17 4 19 21 13
output:
19 // the biggest prime
1 7 // and its positon
So first I get the input, store it in an array, make a copy of that array and sort it (because I use a varible to keep track of the higest prime, and insane thing will happen if that was unsorted) work with every number of that array to check if it is prime, loop through it again to have the positon and print the result.
But the time is too slow, can I improve it?
My code:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int numbersNotSorted[n];
int maxNum{0};
for (int i = 0; i < n; i++)
{
cin >> numbersNotSorted[i];
}
int numbersSorted[n];
for (int i = 0; i < n; i++)
{
numbersSorted[i] = numbersNotSorted[i];
}
sort(numbersSorted, numbersSorted + n);
for (int number = 0; number < n; number++)
{
int countNum{0};
for (int i = 2; i <= sqrt(numbersSorted[number]); i++)
{
if (numbersSorted[number] % i == 0)
countNum++;
}
if (countNum == 0)
{
maxNum = numbersSorted[number];
}
}
cout << maxNum << '\n';
for (int i = 0; i < n; i++)
{
if (numbersNotSorted[i] == maxNum)
cout << i + 1 << ' ';
}
}
If you need the biggest prime, sorting the array brings you no benefit, you'll need to check all the values stored in the array anyway.
Even if you implemented a fast sorting algorithm, the best averages you can hope for are O(N + k), so just sorting the array is actually more costly than looking for the largest prime in an unsorted array.
The process is pretty straight forward, check if the next value is larger than the current largest prime, and if so check if it's also prime, store the positions and/or value if it is, if not, check the next value, repeat until the end of the array.
θ(N) time compexity will be the best optimization possible given the conditions.
Start with a basic "for each number entered" loop:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main() {
int n;
int newNumber;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
}
}
If the new number is smaller than the current largest prime, then it can be ignored.
int main() {
int n;
int newNumber;
int highestPrime;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
if(newNumber >= highestPrime) {
}
}
}
If the new number is equal to the highest prime, then you just need to store its position somewhere. I'm lazy, so:
int main() {
int n;
int newNumber;
int highestPrime;
int maxPositions = 1234;
int positionList[maxPositions];
int nextPosition;
int currentPosition = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
currentPosition++;
if(newNumber >= highestPrime) {
if(newNumber == highestPrime) {
if(nextPosition+1 >= maxPositions) {
// List of positions is too small (should've used malloc/realloc instead of being lazy)!
} else {
positionList[nextPosition++] = currentPosition;
}
}
}
}
}
If the new number is larger than the current largest prime, then you need to figure out if it is a prime number, and if it is you need to reset the list and store its position, etc:
int main() {
int n;
int newNumber;
int highestPrime = 0;
int maxPositions = 1234;
int positionList[maxPositions];
int nextPosition;
int currentPosition = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
currentPosition++;
if(newNumber >= highestPrime) {
if(newNumber == highestPrime) {
if(nextPosition+1 >= maxPositions) {
// List of positions is too small (should've used malloc/realloc instead of being lazy)!
} else {
positionList[nextPosition++] = currentPosition;
}
} else { // newNumber > highestPrime
if(isPrime(newNumber)) {
nextPosition = 0; // Reset the list
highestPrime = newNumber;
positionList[nextPosition++] = currentPosition;
}
}
}
}
}
You'll also want something to display the results:
if(highestPrime > 0) {
for(nextPosition= 0; nextPosition < currentPosition; nextPosition++) {
cout << positionList[nextPosition];
}
}
Now; the only thing you're missing is an isPrime(int n) function. The fastest way to do that is to pre-calculate a "is/isn't prime" bitfield. It might look something like:
bool isPrime(int n) {
if(n & 1 != 0) {
n >>= 1;
if( primeNumberBitfield[n / 32] & (1 << (n % 32)) != 0) {
return true;
}
}
return false;
}
The problem here is that (for positive values in a 32-bit signed integer) you'll need 1 billion bits (or 128 MiB).
To avoid that you can use a much smaller bitfield for numbers up to sqrt(1 << 31) (which is only about 4 KiB); then if the number is too large for the bitfield you can use the bitfield to find prime numbers and check (with modulo) if they divide the original number evenly.
Note that Sieve of Eratosthenes ( https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes ) is an efficient way to generate that smaller bitfield (but is not efficient to use for a sparse population of larger numbers).
If you do it right, you'll probably create the illusion that it's instantaneous because almost all of the work will be done while a human is slowly typing the numbers in (and not left until after all of the numbers have been entered). For a very fast typist you'll have ~2 milliseconds between numbers, and (after the last number is entered) humans can't notice delays smaller than about 10 milliseconds.
But the time is too slow, can I improve it?
Below loop suffers from:
Why check smallest values first? Makes more sense to check largest values first to find the largest prime. Exit the for (... number..) loop early once a prime is found. This takes advantage of the work done by sort().
Once a candidate value is not a prime, quit testing for prime-ness.
.
// (1) Start for other end rather than as below
for (int number = 0; number < n; number++) {
int countNum {0};
for (int i = 2; i <= sqrt(numbersSorted[number]); i++) {
if (numbersSorted[number] % i == 0)
// (2) No point in continuing prime testing, Value is composite.
countNum++;
}
if (countNum == 0) {
maxNum = numbersSorted[number];
}
}
Corrections left for OP to implement.
Advanced: Prime testing is a deep subject and many optimizations (trivial and complex) exist that are better than OP's approach. Yet I suspect the above 2 improvement will suffice for OP.
Brittleness: Code does not well handle the case of no primes in the list or n <= 0.
i <= sqrt(numbersSorted[number]) is prone to FP issues leading to an incorrect results. Recommend i <= numbersSorted[number]/i).
Sorting is O(n * log n). Prime testing, as done here, is O(n * sqrt(n[i])). Sorting does not increase O() of the overall code when the square root of the max value is less than log of n. Sorting is worth doing if the result of the sort is used well.
Code fails if the largest value was 1 as prime test incorrectly identifies 1 as a prime.
Code fails if numbersSorted[number] < 0 due to sqrt().
Simply full-range int prime test:
bool isprime(int num) {
if (num % 2 == 0) return num == 2;
for (int divisor = 3; divisor <= num / divisor; divisor += 2) {
if (num % divisor == 0) return false;
}
return num > 1;
}
If you want to find the prime, don't go for sorting. You'll have to check for all the numbers present in the array then.
You can try this approach to do the same thing, but all within a lesser amount of time:
Step-1: Create a global function for detecting a prime number. Here's how you can approach this-
bool prime(int n)
{
int i, p=1;
for(i=2;i<=sqrt(n);i++) //note that I've iterated till the square root of n, to cut down on the computational time
{
if(n%i==0)
{
p=0;
break;
}
}
if(p==0)
return false;
else
return true;
}
Step-2: Now your main function starts. You take input from the user:
int main()
{
int n, i, MAX;
cout<<"Enter the number of elements: ";
cin>>n;
int arr[n];
cout<<"Enter the array elements: ";
for(i=0;i<n;i++)
cin>>arr[i];
Step-3: Note that I've declared a counter variable MAX. I initialize this variable as the first element of the array: MAX=arr[0];
Step-4: Now the loop for iterating the array. What I did was, I iterated through the array and at each element, I checked if the value is greater than or equal to the previous MAX. This will ensure, that the program does not check the values which are less than MAX, thus eliminating a part of the array and cutting down the time. I then nested another if statement, to check if the value is a prime or not. If both of these are satisfied, I set the value of MAX to the current value of the array:
for(i=0;i<n;i++)
{
if(arr[i]>=MAX) //this will check if the number is greater than the previous MAX number or not
{
if(prime(arr[i])) //if the previous condition satisfies, then only this block of code will run and check if it's a prime or not
MAX=arr[i];
}
}
What happens is this- The value of MAX changes to the max prime number of the array after every single loop.
Step-5: Then, after finally traversing the array, when the program finally comes out of the loop, MAX will have the largest prime number of the array stored in it. Print this value of MAX. Now for getting the positions where MAX happens, just iterate over the whole loop and check for the values that match MAX and print their positions:
for(i=0;i<n;i++)
{
if(arr[i]==MAX)
cout<<i+1<<" ";
}
I ran this code in Dev C++ 5.11 and the compilation time was 0.72s.
I am trying to solve at the following exercise from the C++ Primer Plus book.
Define a recursive function that takes an integer argument and returns
the factorial of that argument. Recall that 3 factorial, written 3!,
equals 3 × 2!, and so on, with 0! defined as 1. In general, if n is
greater than zero, n! = n * (n - 1)!. Test your function in a program
that uses a loop to allow the user to enter various values for which
the program reports the factorial.
I wrote the code that goes into main().
#include <iostream>
using namespace std;
int factorial(int n);
int main()
{
int number= 0;
cout<<"Enter a number(0 to quit): ";
while (cin >> number && number! = 0)
{
cout<< "Here is the factorial of the number: "<< factorial (number) << ". \n"
"Enter next number(0 to quit): ";
}
return 0;
}
Now I can't think of a proper recursive function declaration. Can someone help by writing the easiest (for someone new in programming) to grasp function declaration for this exercise?
When designing a recursive algorithm to calculate the factorial of any number, we must first identify the base case, which is the part of the calculation that we can solve without recursion. That is the case where n = 0 then factorial(n) = 1.
This tells how to solve the problem when nis equal to 0, but what do we do when n is greater than 0? That is the recursive case, or the part of the problem that we use recursion to solve. If n > 0, then factorial(n) = n * factorial(n-1). This states that if n is greater than 0, the factorial of n is n times the factorial of n-1.
int factorial(int n)
{
if (n == 0)
return 1; // base case
else
return n * factorial(n-1); // recursive case
}
I would do something along the lines of:
int factorial(int n){
if(n<=0)
return 1;
int num=factorial(n-1);
if(num)
return n*num;
return 0;
}
You can use very short function as follows, but it the same as the answered provided by #superPhreshHackerKid
int factorial(int n){
if (n > 0)
return n * factorial(n-1);
return 1;
}
Hope it helps
My program seems to be crashing every time it recursive calling in the minimum function. Can anyone tell me why it is crashing. It would instantly freeze after i call the minimum function. Is it because im using a vector?
#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
int minimum(vector<int> denom, int s, int N) //take in denomination , sizeofcoin, and value of N
{
if(N == 0)
{
return 1;
}
else if(N < 0 || (N > 0 && s <=0))
{
return 0;
}
else
{
return min(minimum(denom,s - 1, N), 1 + minimum(denom, s,N-denom[s-1]));
}
}
int main()
{
int N;
unsigned int sizeofcoin;
cout << "Enter the value N to produce: " << endl;
cin >> N;
cout << "Enter the number of different denominations: " << endl;
cin >> sizeofcoin;
vector<int> denom(sizeofcoin);
for(unsigned int i= 0; i < sizeofcoin; i++)
{
cout << "Enter denomination #" << (i+1) << endl; //save all the denominations in an array
cin >> denom[i];
}
sort(denom.begin() , denom.end(),greater<int>()); //sort the array from largest to smallest
if(denom.back() != 1) //check the end of the array (since the back is smallest now) if it has 1
{
denom.push_back(1); //Will include 1 if the user does not input a 1 (doesn't have to be used)
}
minimum(denom,sizeofcoin,N);
return 0;
}
I tried to explain your minimum() function to your rubber duck, and your rubber duck has a question for you. Here's how our conversation went:
int minimum(vector<int> denom, int s, int N) //take in denomination , sizeofcoin, and value of N
{
if(N <= 0)
{
return 0;
}
Me: this minimum() recursive function immediately returns if its third parameter, N, is 0, or negative.
Your Rubber Duck: Ok.
return (minimum(denom,s - 1, N)...
(Here, I tried explaining your first recursion call here, to your rubber duck):
Me: So, this makes a recursive call, with the same parameters, except that the 2nd parameter is decremented. The third parameter is N.
Your Rubber Duck: So, if the third parameter's value, N, is unchanged, and the recursive function returns without recursing only when N is 0 or negative, and the initial call to minimum() passes a value greater than 0 for N, then when exactly do you expect this recursion to stop?
I couldn't answer this question myself, maybe you can explain this to your rubber duck, by yourself. When does recursion stop, here?
You have the recursive call minimum(denom,s - 1, N) so N will never be less than or equal to 0, and the recursion will never end.
This would have been very easy to find out if you learned how to use a debugger, and stepped through the code line by line, and stepped into the recursive calls.
Another thing that I want to point out is that you are trying to return the sum of two values:
(minimum(denom,s - 1, N) + minimum(denom, s,N-denom[s-1])
instead what you should do is:
min(minimum(denom,s - 1, N), 1 + minimum(denom, s,N-denom[s-1]))
The idea is that in first call you've not used any coin but in second call you have used one, so adding 1 for the same.
Look for a Dynamic Programming solution for the same.
https://people.cs.clemson.edu/~bcdean/dp_practice/
I wrote this function that supposed to find smallest positive integer that is divisible by every number 1 through 20. I get "stack overflow error", even though, when I test for numbers 1 through 10, it works just fine.
here is my code:
#include<iostream>
#include<cstdlib>
using namespace std;
// function prototype
int smallPos(int k, int m,int n);
int main(){
printf("the smallest positive number that is divisible by 1 through 20 is %d ", smallPos(1,1,13));
}
int smallPos(int k, int n, int m){
int div=0;
for(int i = n;i<=m;i++) {
if (k%i==0)
div++;
}
if (div==m) {
return k;
} else {
k+=1;
smallPos(k,n,m);
}
}
Why does it happen? The number shouldn't be that big anyway.
Thank you!
The final condition (div == m) will never be true. For div to become equal to m, the number k should be divisible by all of the numbers in range [n,m).
Edit: I've reread the text in the printf() call to understand what the function does. You're looking for the first number divisible by all numbers in the range. If my calculations are correct, this number should be the product of all unique prime factors of the numbers in the range. For the range [1,13] (as per the function call, not the text), this number should be:
30030 = 1 * 2 * 3 * 5 * 7 * 9 * 11 * 13
Now, this means you are going to invoke the function recursively over 30,000 times, which is obviously way too many times for the size of stack you're using (defaults are relatively small). For a range this size, you should really consider writing an iterative function instead.
Edit: here's an iterative version that seems to work.
int smallPos ( int n, int m )
{
int k = 0;
while ( ++k )
{
int count = 0;
for (int i = n; i<=m; i++)
{
if (k%i==0) {
++count;
}
}
if (count == (m-n+1)) {
return k;
}
}
return k;
}
Indeed, the result for smallPos(1,10), the result is 2520. It seems my previous estimate was a lower bound, not a fixed result.
Your smallPos function incurs undefined behaviour since it is not returning a value in all execution paths. You may want to say return smallPos(k,n,m); in the last part (or just return smallPos(k + 1, n, m); in one go).