Open In App

Count the numbers with N digits and whose suffix is divisible by K

Last Updated : 02 Dec, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two positive integers n and k, the task is to count the number of positive integers d such that d has n digits and any of the suffixes of its decimal representation is divisible by k. 

Examples:  

Input: n = 1, k = 2 
Output:
Explanation: There are 4 such integers in which any of the suffix is divisible by k: [2, 4, 6, 8]

Input: n = 2, k = 2 
Output: 45 
Explanation: All the even numbers in the range [10, 99] are divisible by 2.

Using Brute Force Method - O(n*(10^n)) Time and O(1) Space

The idea is to check every possible number of n digits and then verify if any of its suffixes are divisible by k. A suffix is any contiguous number formed by taking the last few digits of the number. For each number, we start from the rightmost digit and build suffixes incrementally, checking if each one is divisible by k. If any suffix of the number is divisible by k, we count that number. We generate all n-digit numbers by iterating from 10^(n-1) to 10^n - 1. The solution involves checking each number and its suffixes, ensuring that at least one suffix meets the divisibility condition.

C++
// C++ program to count the numbers
// with N digits and whose suffix
// is divisible by K.
#include <bits/stdc++.h>
using namespace std;

// Function to check if any suffix of
// num is divisible by k.
bool hasDivisibleSuffix(int num, int k) {
  
    int suffix = 0;
    int base = 1;
    while (num > 0) {
        suffix = (num % 10) * base + suffix;
        if (suffix % k == 0)
            return true;

        num = num / 10;
        base *= 10;
    }

    return false;
}

int count(int n, int k) {
    int ans = 0;

    // Generate all n-digit numbers
    // from 10^(n-1) to 10^n - 1
    int start = (int)pow(10, n - 1);
    int end = (int)pow(10, n);

    for (int num = start; num < end; num++) {
        if (hasDivisibleSuffix(num, k)) {
            ans++;
        }
    }

    return ans;
}

int main() {
  
    int n = 2, k = 2;
    cout << count(n, k);
    return 0;
}
Java
// Java program to count the numbers
// with N digits and whose suffix 
// is divisible by K.
import java.util.*;

class GfG {

    // Function to check if any suffix of 
    // num is divisible by k.
    static boolean hasDivisibleSuffix(int num, int k) {
        int suffix = 0;
        int base = 1;
        while (num > 0) {
            suffix = (num % 10) * base + suffix;
            if (suffix % k == 0) return true;
            
            num = num / 10;
            base *= 10;
        }
        
        return false;
    }

    static int count(int n, int k) {
        int ans = 0;
        
        // Generate all n-digit numbers 
        // from 10^(n-1) to 10^n - 1
        int start = (int) Math.pow(10, n - 1);
        int end = (int) Math.pow(10, n);
        
        for (int num = start; num < end; num++) {
            if (hasDivisibleSuffix(num, k)) {
                ans++;
            }
        }
        
        return ans;
    }

    public static void main(String[] args) {
        int n = 2, k = 2; 
        System.out.println(count(n, k));
    }
}
Python
# Python program to count the numbers
# with N digits and whose suffix 
# is divisible by K.

# Function to check if any suffix of 
# num is divisible by k.
def hasDivisibleSuffix(num, k):
    suffix = 0
    base = 1
    while num > 0:
        suffix = (num % 10) * base + suffix
        if suffix % k == 0:
            return True
        num = num // 10
        base *= 10
    return False

def count(n, k):
    ans = 0
    
    # Generate all n-digit numbers 
    # from 10^(n-1) to 10^n - 1
    start = 10**(n-1)
    end = 10**n
    
    for num in range(start, end):
        if hasDivisibleSuffix(num, k):
            ans += 1
    
    return ans

if __name__ == "__main__":
    n = 2
    k = 2
    print(count(n, k))
C#
// C# program to count the numbers
// with N digits and whose suffix 
// is divisible by K.
using System;

class GfG {

    // Function to check if any suffix of 
    // num is divisible by k.
    static bool hasDivisibleSuffix(int num, int k) {
        int suffix = 0;
        int baseVal = 1;
        while (num > 0) {
            suffix = (num % 10) * baseVal + suffix;
            if (suffix % k == 0) return true;
            
            num = num / 10;
            baseVal *= 10;
        }
        
        return false;
    }

    static int count(int n, int k) {
        int ans = 0;
        
        // Generate all n-digit numbers 
        // from 10^(n-1) to 10^n - 1
        int start = (int)Math.Pow(10, n - 1);
        int end = (int)Math.Pow(10, n);
        
        for (int num = start; num < end; num++) {
            if (hasDivisibleSuffix(num, k)) {
                ans++;
            }
        }
        
        return ans;
    }

    static void Main() {
        int n = 2, k = 2; 
        Console.WriteLine(count(n, k));
    }
}
JavaScript
// JavaScript program to count the numbers
// with N digits and whose suffix 
// is divisible by K.

// Function to check if any suffix of 
// num is divisible by k.
function hasDivisibleSuffix(num, k) {
    let suffix = 0;
    let base = 1;
    while (num > 0) {
        suffix = (num % 10) * base + suffix;
        if (suffix % k == 0) return true;
        
        num = Math.floor(num / 10);
        base *= 10;
    }
    return false;
}

function count(n, k) {
    let ans = 0;
    
    // Generate all n-digit numbers 
    // from 10^(n-1) to 10^n - 1
    let start = Math.pow(10, n - 1);
    let end = Math.pow(10, n);
    
    for (let num = start; num < end; num++) {
        if (hasDivisibleSuffix(num, k)) {
            ans++;
        }
    }
    
    return ans;
}

let n = 2, k = 2;
console.log(count(n, k));

Output
45

Using Dynamic Programming Approach - O(n*k) Time and O(n*k) Space

The idea is to use a digit dynamic programming (Digit DP) approach, where we recursively build the number digit by digit, from the least significant digit (LSB) to the most significant digit (MSB), while considering whether any of the suffixes of the number is divisible by k. At each step, we keep track of the remainder of the number modulo k as well as whether any suffix encountered so far has been divisible by k.

Each state in DP will be:

  • i: Current digit position (starting from 0 for the least significant digit and moving to n-1 for the most significant digit).
  • rem: The remainder of the number formed by the digits chosen so far, modulo k.
  • divisible: A boolean flag indicating whether any of the suffixes formed so far is divisible by k. Initially, it is set to false, and we set it to true once we encounter a suffix divisible by k.
C++
// C++ program to count the numbers
// with N digits and whose suffix 
// is divisible by K.
#include <bits/stdc++.h>
using namespace std;

// Recursive function to count numbers 
// whose suffixes are divisible by k
int countRecur(int i, int rem, int divisible, 
int n, int k, vector<vector<vector<int>>> &memo) {
    
    // Base case:
    if (i == n) {
        
        // If any suffix encountered 
        // is divisible by K, return 1
        return divisible == 1 ? 1 : 0;
    }
    
    if (memo[i][rem][divisible] != -1) {
        return memo[i][rem][divisible];
    }
    
    // Set the minimum value for the current digit
    int minLimit = (i == n - 1) ? 1 : 0;
    int ans = 0;
    
    // Try all possible digits for the current position
    for (int digit = minLimit; digit <= 9; digit++) {
        
        // Calculate the remainder when this 
        // digit is added to the current number
        int power = (int)(pow(10, i)); 
        int newRem = (rem + digit * power) % k;
        
        ans += countRecur(i + 1, newRem, 
        divisible || newRem == 0, n, k, memo);
    }
    
    // Store the result for this 
    //state in the memoization table
    return memo[i][rem][divisible] = ans;
}

int count(int n, int k) {
    vector<vector<vector<int>>> memo(n, 
    vector<vector<int>>(k, vector<int>(2, -1)));
    return countRecur(0, 0, 0, n, k, memo);
}

int main() {
    int n = 2, k = 2; 
    cout << count(n, k);
    return 0;
} 
Java
// Java program to count the numbers
// with N digits and whose suffix 
// is divisible by K.

import java.util.Arrays;

class GfG {

    // Recursive function to count numbers 
    // whose suffixes are divisible by K
    static int countRecur(int i, int rem, int divisible, 
    int n, int k, int[][][] memo) {
        
        // Base case:
        if (i == n) {
            
            // If any suffix encountered 
            // is divisible by K, return 1
            return divisible == 1 ? 1 : 0;
        }
        
        if (memo[i][rem][divisible] != -1) {
            return memo[i][rem][divisible];
        }
        
        // Set the minimum value for the current digit
        int minLimit = (i == n - 1) ? 1 : 0;
        int ans = 0;
        
        // Try all possible digits for the current position
        for (int digit = minLimit; digit <= 9; digit++) {
            
            // Calculate the remainder when this 
            // digit is added to the current number
            int power = (int)(Math.pow(10, i)); 
            int newRem = (rem + digit * power) % k;
            
            ans += countRecur(i + 1, newRem, 
            (divisible==1 || newRem==0)?1:0, n, k, memo);
        }
        
        // Store the result for this 
        // state in the memoization table
        return memo[i][rem][divisible] = ans;
    }

    static int count(int n, int k) {
        int[][][] memo = new int[n][k][2];
        for (int[][] row : memo) {
            for (int[] subRow : row) {
                Arrays.fill(subRow, -1);
            }
        }
        return countRecur(0, 0, 0, n, k, memo);
    }

    public static void main(String[] args) {
        int n = 2, k = 2; 
        System.out.println(count(n, k));
    }
}
Python
# Python program to count the numbers
# with N digits and whose suffix 
# is divisible by K.

def countRecur(i, rem, divisible, n, k, memo):

    # Base case:
    if i == n:
        
        # If any suffix encountered 
        # is divisible by K, return 1
        return 1 if divisible == 1 else 0
    
    if memo[i][rem][divisible] != -1:
        return memo[i][rem][divisible]
    
    # Set the minimum value for the current digit
    minLimit = 1 if i == n - 1 else 0
    ans = 0
    
    # Try all possible digits for the current position
    for digit in range(minLimit, 10):
        
        # Calculate the remainder when this 
        # digit is added to the current number
        power = 10 ** i
        newRem = (rem + digit * power) % k
        
        ans += countRecur(i + 1, newRem, 
        divisible or newRem == 0, n, k, memo)
    
    # Store the result for this 
    # state in the memoization table
    memo[i][rem][divisible] = ans
    return ans

def count(n, k):
    memo = [[[-1 for _ in range(2)] for _ in range(k)] for _ in range(n)]
    return countRecur(0, 0, 0, n, k, memo)

if __name__ == "__main__":
    n = 2
    k = 2
    print(count(n, k))
C#
// C# program to count the numbers
// with N digits and whose suffix 
// is divisible by K.

using System;

class GfG {

    // Recursive function to count numbers 
    // whose suffixes are divisible by K
    static int countRecur(int i, int rem, int divisible, 
    int n, int k, int[,,] memo) {
        
        // Base case:
        if (i == n) {
            
            // If any suffix encountered 
            // is divisible by K, return 1
            return divisible == 1 ? 1 : 0;
        }
        
        if (memo[i, rem, divisible] != -1) {
            return memo[i, rem, divisible];
        }
        
        // Set the minimum value for the current digit
        int minLimit = (i == n - 1) ? 1 : 0;
        int ans = 0;
        
        // Try all possible digits for the current position
        for (int digit = minLimit; digit <= 9; digit++) {
            
            // Calculate the remainder when this 
            // digit is added to the current number
            int power = (int)Math.Pow(10, i); 
            int newRem = (rem + digit * power) % k;
            
            ans += countRecur(i + 1, newRem, 
            divisible==1 || (newRem == 0)?1:0, n, k, memo);
        }
        
        // Store the result for this 
        // state in the memoization table
        memo[i, rem, divisible] = ans;
        return ans;
    }

    static int count(int n, int k) {
        int[,,] memo = new int[n, k, 2];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < k; j++) {
                for (int z = 0; z < 2; z++) {
                    memo[i, j, z] = -1;
                }
            }
        }
        return countRecur(0, 0, 0, n, k, memo);
    }

    static void Main(string[] args) {
        int n = 2, k = 2; 
        Console.WriteLine(count(n, k));
    }
}
JavaScript
// JavaScript program to count the numbers
// with N digits and whose suffix 
// is divisible by K.

function countRecur(i, rem, divisible, 
n, k, memo) {

    // Base case:
    if (i === n) {
        
        // If any suffix encountered 
        // is divisible by K, return 1
        return divisible === 1 ? 1 : 0;
    }
    
    if (memo[i][rem][divisible] !== -1) {
        return memo[i][rem][divisible];
    }
    
    // Set the minimum value for the current digit
    const minLimit = i === n - 1 ? 1 : 0;
    let ans = 0;
    
    // Try all possible digits for the current position
    for (let digit = minLimit; digit <= 9; digit++) {
        
        // Calculate the remainder when this 
        // digit is added to the current number
        const power = Math.pow(10, i);
        const newRem = (rem + digit * power) % k;
        
        ans += countRecur(i + 1, newRem, 
        divisible===1 || newRem === 0?1:0, n, k, memo);
    }
    
    // Store the result for this 
    // state in the memoization table
    memo[i][rem][divisible] = ans;
    return ans;
}

function count(n, k) {
    const memo = Array.from({ length: n }, () => 
    Array.from({ length: k }, () => Array(2).fill(-1)));
    return countRecur(0, 0, 0, n, k, memo);
}

const n = 2, k = 2;
console.log(count(n, k));

Output
45

Next Article

Similar Reads