Given a positive integer N, the task is to count the number of N-digit numbers such that the bitwise AND of adjacent digits equals 0.
Examples:
Input: N = 1
Output: 10
Explanation: All numbers from 0 to 9 satisfy the given condition as there is only one digit.Input: N = 3
Output: 264
Naive Approach: The simplest approach to solve the given problem is to iterate over all possible N-digit numbers and count those numbers whose bitwise AND of adjacent digits is 0. After checking for all the numbers, print the value of count as the result.
Time Complexity: O(N × 10N)
Auxiliary Space: O(1)
Efficient Approach: The above approach can also be optimized by using Dynamic Programming because the above problem has Overlapping subproblems and an Optimal substructure. The subproblems can be stored in dp[][] table using memoization where dp[digit][prev] stores the answer from the digitth position till the end, when the previous digit selected is prev. Follow the steps below to solve the problem:
- Define a recursive function, say countOfNumbers(digit, prev) by performing the following steps.
- If the value of digit is equal to N + 1 then return 1 as a valid N-digit number is formed.
- If the result of the state dp[digit][prev] is already computed, return this state dp[digit][prev].
- If the current digit is 1, then any digit from [1, 9] can be placed. If N = 1, then 0 can be placed as well.
- Otherwise, iterate through all the numbers from i = 0 to i = 9, and check if the condition ((i & prev) == 0) holds valid or not and accordingly place satisfying ‘i’ values in the current position.
- After making a valid placement, recursively call the countOfNumbers function for index (digit + 1).
- Return the sum of all possible valid placements of digits as the answer.
- Print the value returned by the function countOfNumbers(1, 0, N) as the result.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
int dp[100][10];
// Function to calculate count of 'N' digit // numbers such that bitwise AND of adjacent // digits is 0. int countOfNumbers( int digit, int prev, int n)
{ // If digit = n + 1, a valid
// n-digit number has been formed
if (digit == n + 1) {
return 1;
}
// If the state has
// already been computed
int & val = dp[digit][prev];
if (val != -1) {
return val;
}
val = 0;
// If current position is 1,
// then any digit from [1-9] can be placed.
// If n = 1, 0 can be also placed.
if (digit == 1) {
for ( int i = (n == 1 ? 0 : 1); i <= 9; ++i) {
val += countOfNumbers(digit + 1, i, n);
}
}
// For remaining positions,
// any digit from [0-9] can be placed
// after checking the conditions.
else {
for ( int i = 0; i <= 9; ++i) {
// Check if bitwise AND
// of current digit and
// previous digit is 0.
if ((i & prev) == 0) {
val += countOfNumbers(digit + 1, i, n);
}
}
}
// Return answer
return val;
} // Driver code int main()
{ // Initialize dp array with -1.
memset (dp, -1, sizeof dp);
// Given Input
int N = 3;
// Function call
cout << countOfNumbers(1, 0, N) << endl;
} |
// Java program for the above approach import java.util.*;
class GFG{
static int dp[][] = new int [ 100 ][ 10 ];
// Function to calculate count of 'N' digit // numbers such that bitwise AND of adjacent // digits is 0. static int countOfNumbers( int digit, int prev, int n)
{ // If digit = n + 1, a valid
// n-digit number has been formed
if (digit == n + 1 )
{
return 1 ;
}
// If the state has
// already been computed
int val = dp[digit][prev];
if (val != - 1 )
{
return val;
}
val = 0 ;
// If current position is 1,
// then any digit from [1-9] can be placed.
// If n = 1, 0 can be also placed.
if (digit == 1 )
{
for ( int i = (n == 1 ? 0 : 1 ); i <= 9 ; ++i)
{
val += countOfNumbers(digit + 1 , i, n);
}
}
// For remaining positions,
// any digit from [0-9] can be placed
// after checking the conditions.
else
{
for ( int i = 0 ; i <= 9 ; ++i)
{
// Check if bitwise AND
// of current digit and
// previous digit is 0.
if ((i & prev) == 0 )
{
val += countOfNumbers(digit + 1 , i, n);
}
}
}
// Return answer
return val;
} // Driver code public static void main(String[] args)
{ // Initializing dp array with -1.
for ( int i = 0 ; i < 100 ; i++)
{
for ( int j = 0 ; j < 10 ; j++)
{
dp[i][j] = - 1 ;
}
}
// Given Input
int N = 3 ;
// Function call
System.out.println(countOfNumbers( 1 , 0 , N));
} } // This code is contributed by sanjoy_62 |
# Python3 program for the above approach dp = [[ - 1 for i in range ( 10 )]
for j in range ( 100 )]
val = 0
# Function to calculate count of 'N' digit # numbers such that bitwise AND of adjacent # digits is 0. def countOfNumbers(digit, prev, n):
global val
global dp
# If digit = n + 1, a valid
# n-digit number has been formed
if (digit = = n + 1 ):
return 1
# If the state has
# already been computed
val = dp[digit][prev]
if (val ! = - 1 ):
return val
val = 0
# If current position is 1,
# then any digit from [1-9] can be placed.
# If n = 1, 0 can be also placed.
if (digit = = 1 ):
i = 0 if n = = 1 else 1
while (i < = 9 ):
val + = countOfNumbers(digit + 1 , i, n)
i + = 1
# For remaining positions,
# any digit from [0-9] can be placed
# after checking the conditions.
else :
for i in range ( 10 ):
# Check if bitwise AND
# of current digit and
# previous digit is 0.
if ((i & prev) = = 0 ):
val + = countOfNumbers(digit + 1 , i, n)
# Return answer
return val
# Driver code if __name__ = = '__main__' :
# Given Input
N = 3
# Function call
print (countOfNumbers( 1 , 0 , N))
# This code is contributed by SURENDRA_GANGWAR |
// C# program for the above approach using System;
class GFG
{ static int [,] dp = new int [100, 10];
// Function to calculate count of 'N' digit
// numbers such that bitwise AND of adjacent
// digits is 0.
static int countOfNumbers( int digit, int prev, int n)
{
// If digit = n + 1, a valid
// n-digit number has been formed
if (digit == n + 1)
{
return 1;
}
// If the state has
// already been computed
int val = dp[digit, prev];
if (val != -1)
{
return val;
}
val = 0;
// If current position is 1,
// then any digit from [1-9] can be placed.
// If n = 1, 0 can be also placed.
if (digit == 1)
{
for ( int i = (n == 1 ? 0 : 1); i <= 9; ++i)
{
val += countOfNumbers(digit + 1, i, n);
}
}
// For remaining positions,
// any digit from [0-9] can be placed
// after checking the conditions.
else
{
for ( int i = 0; i <= 9; ++i)
{
// Check if bitwise AND
// of current digit and
// previous digit is 0.
if ((i & prev) == 0)
{
val += countOfNumbers(digit + 1, i, n);
}
}
}
// Return answer
return val;
}
// Driver code
public static void Main( string [] args)
{
// Initializing dp array with -1.
for ( int i = 0; i < 100; i++)
{
for ( int j = 0; j < 10; j++)
{
dp[i, j] = -1;
}
}
// Given Input
int N = 3;
// Function call
Console.WriteLine(countOfNumbers(1, 0, N));
}
} // This code is contributed by avijitmondal1998. |
<script> // JavaScript program for the above approach
// Function to calculate count of 'N' digit
// numbers such that bitwise AND of adjacent
// digits is 0.
function countOfNumbers(digit, prev, n)
{
// If digit = n + 1, a valid
// n-digit number has been formed
if (digit == n + 1) {
return 1;
}
// If the state has
// already been computed
let val = dp[digit][prev];
if (val != -1) {
return val;
}
val = 0;
// If current position is 1,
// then any digit from [1-9] can be placed.
// If n = 1, 0 can be also placed.
if (digit == 1) {
for (let i = (n == 1 ? 0 : 1); i <= 9; ++i) {
val += countOfNumbers(digit + 1, i, n);
}
}
// For remaining positions,
// any digit from [0-9] can be placed
// after checking the conditions.
else {
for (let i = 0; i <= 9; ++i) {
// Check if bitwise AND
// of current digit and
// previous digit is 0.
if ((i & prev) == 0) {
val += countOfNumbers(digit + 1, i, n);
}
}
}
// Return answer
return val;
}
// Initialize dp array with -1.
let dp = Array(100).fill().map(() =>
Array(10).fill(-1));
// Given Input
let N = 3;
// Function call
document.write(countOfNumbers(1, 0, N) + "<br>" );
// This code is contributed by Potta Lokesh
</script>
|
264
Time Complexity: O(N × 102)
Auxiliary Space: O(N × 10)