Open In App

Count numbers which can be constructed using two numbers

Given three positive integers x, y and n, the task is to find count of all numbers from 1 to n that can be formed using x and y. A number can be formed using x and y if we can get it by adding any number of occurrences of x and/or y.
Examples : 

Input  : n = 10, x = 2, y = 3
Output : 9
We can form 9 out of 10 numbers using 2 and 3
2 = 2, 3 = 3, 4 = 2+2, 5 = 2+3, 6 = 3+3
7 = 2+2+3, 8 = 3+3+2, 9 = 3+3+3
and 10 = 3+3+2+2.

Input : n = 10, x = 5, y = 7
Output : 3
We can form 3 out of 10 numbers using 5 and 7
The numbers are 5, 7 and 10
Input : n = 15, x = 5, y = 7
Output : 6
We can form 6 out of 10 numbers using 5 and 7.
The numbers are 5, 7, 10, 12, 14 and 15.
Input : n = 15, x = 2, y = 4
Output : 7

A simple solution is to write a recursive code that starts with 0 and makes two recursive calls. One recursive call adds x and other adds y. This way we count total numbers. We need to make sure a number is counted multiple times.
An efficient solution solution is to use a boolean array arr[] of size n+1. An entry arr[i] = true is going to mean that i can be formed using x and y. We initialize arr[x] and arr[y] as true if x and y are smaller than or equal to n. We start traversing the array from smaller of two numbers and mark all numbers one by one that can be formed using x and y.



 Below is the implementation.




// C++ program to count all numbers that can
// be formed using two number numbers x an y
#include<bits/stdc++.h>
using namespace std;
 
// Returns count of numbers from 1 to n that can be formed
// using x and y.
int countNums(int n, int x, int y)
{
    // Create an auxiliary array and initialize it
    // as false. An entry arr[i] = true is going to
    // mean that i can be formed using x and y
    vector<bool> arr(n+1, false);
 
    // x and y can be formed using x and y.
    if (x <= n)
        arr[x] = true;
    if (y <= n)
        arr[y] = true;
 
    // Initialize result
    int result = 0;
 
    // Traverse all numbers and increment
    // result if a number can be formed using
    // x and y.
    for (int i=min(x, y); i<=n; i++)
    {
        // If i can be formed using x and y
        if (arr[i])
        {
            // Then i+x and i+y can also be formed
            // using x and y.              
            if (i+x <= n)
                arr[i+x] = true;
            if (i+y <= n)
                arr[i+y] = true;
 
            // Increment result
            result++;
        }
    }
    return result;
}
 
// Driver code
int main()
{
    int n = 15, x = 5, y = 7;
    cout << countNums(n, x, y);
    return 0;
}




// Java program to count all numbers that can
// be formed using two number numbers x an y
 
class gfg{
// Returns count of numbers from 1 to n that can be formed
// using x and y.
static int countNums(int n, int x, int y)
{
    // Create an auxiliary array and initialize it
    // as false. An entry arr[i] = true is going to
    // mean that i can be formed using x and y
    boolean[] arr=new boolean[n+1];
 
    // x and y can be formed using x and y.
    if (x <= n)
        arr[x] = true;
    if (y <= n)
        arr[y] = true;
 
    // Initialize result
    int result = 0;
 
    // Traverse all numbers and increment
    // result if a number can be formed using
    // x and y.
    for (int i=Math.min(x, y); i<=n; i++)
    {
        // If i can be formed using x and y
        if (arr[i])
        {
            // Then i+x and i+y can also be formed
            // using x and y.            
            if (i+x <= n)
                arr[i+x] = true;
            if (i+y <= n)
                arr[i+y] = true;
 
            // Increment result
            result++;
        }
    }
    return result;
}
 
// Driver code
public static void main(String[] args)
{
    int n = 15, x = 5, y = 7;
    System.out.println(countNums(n, x, y));
}
}
// This code is contributed by mits




# Python3 program to count all numbers
# that can be formed using two number
# numbers x an y
 
# Returns count of numbers from 1
# to n that can be formed using x and y.
def countNums(n, x, y):
 
    # Create an auxiliary array and
    # initialize it as false. An
    # entry arr[i] = True is going to
    # mean that i can be formed using
    # x and y
    arr = [False for i in range(n + 2)]
 
    # x and y can be formed using x and y.
    if(x <= n):
        arr[x] = True
    if(y <= n):
        arr[y] = True
 
    # Initialize result
    result = 0
 
    # Traverse all numbers and increment
    # result if a number can be formed
    # using x and y.
    for i in range(min(x, y), n + 1):
 
        # If i can be formed using x and y
        if(arr[i]):
 
            # Then i+x and i+y can also
            # be formed using x and y.
            if(i + x <= n):
                arr[i + x] = True
            if(i + y <= n):
                arr[i + y] = True
 
            # Increment result
            result = result + 1
 
    return result
 
# Driver code
n = 15
x = 5
y = 7
print(countNums(n, x, y))
 
# This code is contributed by
# Sanjit_Prasad




// C# program to count all numbers that can
// be formed using two number numbers x an y
 
using System;
 
public class GFG{
    // Returns count of numbers from 1 to n that can be formed
// using x and y.
static int countNums(int n, int x, int y)
{
    // Create an auxiliary array and initialize it
    // as false. An entry arr[i] = true is going to
    // mean that i can be formed using x and y
    bool []arr=new bool[n+1];
 
    // x and y can be formed using x and y.
    if (x <= n)
        arr[x] = true;
    if (y <= n)
        arr[y] = true;
 
    // Initialize result
    int result = 0;
 
    // Traverse all numbers and increment
    // result if a number can be formed using
    // x and y.
    for (int i=Math.Min(x, y); i<=n; i++)
    {
        // If i can be formed using x and y
        if (arr[i])
        {
            // Then i+x and i+y can also be formed
            // using x and y.            
            if (i+x <= n)
                arr[i+x] = true;
            if (i+y <= n)
                arr[i+y] = true;
 
            // Increment result
            result++;
        }
    }
    return result;
}
 
// Driver code
    static public void Main (){
        int n = 15, x = 5, y = 7;
        Console.WriteLine(countNums(n, x, y));
    }
}




<script>
// javascript program to count all numbers that can
// be formed using two number numbers x an y
 
// Returns count of numbers from 1 to n that can be formed
// using x and y.
function countNums(n, x, y)
{
 
    // Create an auxiliary array and initialize it
    // as false. An entry arr[i] = true is going to
    // mean that i can be formed using x and y
    arr= Array(n+1).fill(false);
 
    // x and y can be formed using x and y.
    if (x <= n)
        arr[x] = true;
    if (y <= n)
        arr[y] = true;
 
    // Initialize result
    var result = 0;
 
    // Traverse all numbers and increment
    // result if a number can be formed using
    // x and y.
    for (i = Math.min(x, y); i <= n; i++)
    {
     
        // If i can be formed using x and y
        if (arr[i])
        {
         
            // Then i+x and i+y can also be formed
            // using x and y.            
            if (i + x <= n)
                arr[i + x] = true;
            if (i + y <= n)
                arr[i + y] = true;
 
            // Increment result
            result++;
        }
    }
    return result;
}
 
// Driver code
var n = 15, x = 5, y = 7;
document.write(countNums(n, x, y));
 
// This code is contributed by Princi Singh
</script>




<?php
// PHP program to count all numbers
// that can be formed using two
// number numbers x an y
 
// Returns count of numbers from
// 1 to n that can be formed
// using x and y.
function countNums($n, $x, $y)
{
    // Create an auxiliary array and
    // initialize it as false. An
    // entry arr[i] = true is going
    // to mean that i can be formed
    // using x and y
    $arr = array_fill(0, $n + 1, false);
 
    // x and y can be formed
    // using x and y.
    if ($x <= $n)
        $arr[$x] = true;
    if ($y <= $n)
        $arr[$y] = true;
 
    // Initialize result
    $result = 0;
 
    // Traverse all numbers and increment
    // result if a number can be formed
    // using x and y.
    for ($i = min($x, $y); $i <= $n; $i++)
    {
        // If i can be formed using
        // x and y
        if ($arr[$i])
        {
            // Then i+x and i+y can also
            // be formed using x and y.        
            if ($i + $x <= $n)
                $arr[$i + $x] = true;
            if ($i+$y <= $n)
                $arr[$i + $y] = true;
 
            // Increment result
            $result++;
        }
    }
    return $result;
}
 
// Driver code
$n = 15;
$x = 5;
$y = 7;
echo countNums($n, $x, $y);
 
// This code is contributed by mits
?>

Output

6







Time Complexity: O(n) 
Auxiliary Space: O(n)

Approach 2: Using DP:

This code implements a dynamic programming approach to solve a problem of counting the number of integers that can be formed using two given integers x and y, up to a given integer n.

This approach utilizes the previously computed results stored in the dp table to avoid redundant computations, thus improving the efficiency of the algorithm.




#include<bits/stdc++.h>
using namespace std;
 
int countNumsDP(int n, int x, int y, vector<int>& dp) {
    if(n == 0) return 0; // Base case
    if(dp[n] != -1) return dp[n]; // If result already computed, return it
 
    vector<bool> arr(n+1, false); // Array to store intermediate results
    if(x <= n) arr[x] = true; // x and y can be formed using x and y.
    if(y <= n) arr[y] = true;
 
    int result = 0; // Initialize result
 
    // Traverse all numbers and increment result if a number can be formed using x and y.
    for(int i=min(x, y); i<=n; i++) {
        if(arr[i]) { // If i can be formed using x and y
            if(i+x <= n) arr[i+x] = true; // Then i+x and i+y can also be formed using x and y.
            if(i+y <= n) arr[i+y] = true;
 
            result++; // Increment result
        }
    }
 
    dp[n] = result; // Store the result in dp table
    return result;
}
 
int main() {
    int n = 15, x = 5, y = 7;
    vector<int> dp(n+1, -1); // Initialize dp table with -1
    cout << countNumsDP(n, x, y, dp) << endl; // Call DP function
    return 0;
}




import java.util.Arrays;
 
public class GFG {
 
    // Function to count the number of integers that can be formed using x and y
    static int countNumsDP(int n, int x, int y, int[] dp) {
        if (n == 0)
            return 0; // Base case
        if (dp[n] != -1)
            return dp[n]; // If result already computed, return it
 
        boolean[] arr = new boolean[n + 1]; // Array to store intermediate results
        if (x <= n)
            arr[x] = true; // x and y can be formed using x and y.
        if (y <= n)
            arr[y] = true;
 
        int result = 0; // Initialize result
 
        // Traverse all numbers and increment result if a number can be formed using x and y.
        for (int i = Math.min(x, y); i <= n; i++) {
            if (arr[i]) { // If i can be formed using x and y
                if (i + x <= n)
                    arr[i + x] = true; // Then i+x and i+y can also be formed using x and y.
                if (i + y <= n)
                    arr[i + y] = true;
 
                result++; // Increment result
            }
        }
 
        dp[n] = result; // Store the result in dp table
        return result;
    }
 
    public static void main(String[] args) {
        int n = 15, x = 5, y = 7;
        int[] dp = new int[n + 1];
        Arrays.fill(dp, -1); // Initialize dp table with -1
        System.out.println(countNumsDP(n, x, y, dp)); // Call DP function
    }
}




def countNumsDP(n, x, y, dp):
    if n == 0:
        return 0  # Base case
    if dp[n] != -1:
        return dp[n]  # If result already computed, return it
 
    arr = [False] * (n + 1# Array to store intermediate results
    if x <= n:
        arr[x] = True  # x and y can be formed using x and y.
    if y <= n:
        arr[y] = True
 
    result = 0  # Initialize result
 
    # Traverse all numbers and increment result if a number can be formed using x and y.
    for i in range(min(x, y), n + 1):
        if arr[i]:  # If i can be formed using x and y
            if i + x <= n:
                # Then i+x and i+y can also be formed using x and y.
                arr[i + x] = True
            if i + y <= n:
                arr[i + y] = True
 
            result += 1  # Increment result
 
    dp[n] = result  # Store the result in dp table
    return result
 
 
def main():
    n = 15
    x = 5
    y = 7
    dp = [-1] * (n + 1# Initialize dp table with -1
    print(countNumsDP(n, x, y, dp))  # Call DP function
 
 
if __name__ == "__main__":
    main()
     
# This code is contributed by shivamgupta310570




using System;
using System.Collections.Generic;
 
class GFG {
    static int CountNumsDP(int n, int x, int y, List<int> dp) {
        if (n == 0) return 0; // Base case
        if (dp[n] != -1) return dp[n]; // If result already computed, return it
 
        List<bool> arr = new List<bool>(n + 1);
        for (int i = 0; i <= n; i++) {
            arr.Add(false);
        }
 
        if (x <= n) arr[x] = true;
        if (y <= n) arr[y] = true;
 
        int result = 0;
 
        for (int i = Math.Min(x, y); i <= n; i++) {
            if (arr[i]) {
                if (i + x <= n) arr[i + x] = true;
                if (i + y <= n) arr[i + y] = true;
 
                result++;
            }
        }
 
        dp[n] = result;
        return result;
    }
 
    public static void Main(string[] args) {
        int n = 15, x = 5, y = 7;
        List<int> dp = new List<int>(n + 1);
        for (int i = 0; i <= n; i++) {
            dp.Add(-1);
        }
 
        Console.WriteLine(CountNumsDP(n, x, y, dp));
    }
}




//Javascript code for the above approach
function countNumsDP(n, x, y, dp) {
    if (n === 0) return 0; // Base case
    if (dp[n] !== -1) return dp[n]; // If result already computed, return it
 
    const arr = new Array(n + 1).fill(false); // Array to store intermediate results
    if (x <= n) arr[x] = true; // x and y can be formed using x and y.
    if (y <= n) arr[y] = true;
 
    let result = 0; // Initialize result
 
    // Traverse all numbers and increment result if a number can be formed using x and y.
    for (let i = Math.min(x, y); i <= n; i++) {
        if (arr[i]) { // If i can be formed using x and y
            if (i + x <= n) arr[i + x] = true; // Then i+x and i+y can also be
                                               // formed using x and y.
            if (i + y <= n) arr[i + y] = true;
 
            result++; // Increment result
        }
    }
 
    dp[n] = result; // Store the result in dp table
    return result;
}
 
function main() {
    const n = 15, x = 5, y = 7;
    const dp = new Array(n + 1).fill(-1); // Initialize dp table with -1
    console.log(countNumsDP(n, x, y, dp)); // Call DP function
}
 
main();

Output
6








Time complexity: O(n * min(x, y))
Auxiliary Space: O(n)



 


Article Tags :