Given integers, L and R, the task is to find the ?f(x) for all L to R, where f(x) is defined for number as f(x) = (sum of digits on odd positions of x – the sum of digits on even positions of x).
Examples:
Input: L =10, R =15
Output: -9
Explanation:
- f(10) = 1 – 0 = 1
- f(11) = 1 – 1 = 0
- f(12) = 1 – 2 = -1
- f(13) = 1 – 3 = -2
- f(14) = 1 – 4 = -3
- f(15) = 1 – 5 = -4
Total sum = f(10) + f(11) + f(12) + f(13) + f(14) + f(15) = 1 + 0 – 1 – 2 – 3 – 4 = – 9
Input: L = 101, R = 105
Output: 20
Explanation:
- f(101) = 1 – 0 + 1 = 2
- f(102) = 1 – 0 + 2 = 3
- f(103) = 1 – 0 + 3 = 4
- f(104) = 1 – 0 + 4 = 5
- f(105) = 1 – 0 + 5 = 6
Total sum = f(101) + f(102) + f(103) + f(104) + f(105) = 2 + 3 + 4 + 5 + 6 = 20
Naive approach: The basic way to solve the problem is as follows:
The basic way to solve this problem is to generate all possible combinations by using a recursive approach.
Time Complexity: O(N10)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following idea:
Dynamic programming can be used to solve this problem
- dp[i][j][k][l] represents sum of forming i digit number with j as tight condition, k as current sum and l tells whether current position odd or even of number.
- It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly. So the idea is to store the value of each state.
- This can be done using by store the value of a state and whenever the function is called, return the stored value without computing again.
Follow the steps below to solve the problem:
- Create a recursive function that takes four parameters i representing the current position to be filled, j as the tight condition, k as the current sum, and l which indicates the current position is odd or even.
- Call recursive function for all 0 to 9.
- Create an 4d array of dp[20][2][360][2] with initially filled with -1.
- If the answer for a particular state is computed then save it in dp[i][j][k][l].
- If the answer for a particular state is already computed then just return dp[i][j][k][l].
Below is the implementation of the above approach.
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// DP table initialized with -1 int dp[20][2][360][2];
// Recursive Function to find numbers // summation of f(x) in the range L to R int recur( int i, int j, int k, int l, string& a)
{ // Base case
if (i == a.size()) {
return k;
}
// If answer for current state is
// already calculated then just return
// dp[i][j][k][l] +180 is offset to
// store negative values
if (dp[i][j][k + 180][l] != -1)
return dp[i][j][k + 180][l];
// Answer initialized with zero
int ans = 0;
// MaxValue that can be traversed
int maxValue = j == 1 ? a[i] - 48 : 9;
// If first non integer digit
// not taken
if (l == 0) {
// Traversing from 0 to maxValue
for ( int digit = 0; digit <= maxValue; digit++) {
// Calling recursive function
// for maxValue digit
if (digit == maxValue)
ans += recur(i + 1, j, k + digit, 1, a);
// Calling recursive function
// for non-zero digit
else if (digit != 0)
ans += recur(i + 1, 0, k + digit, 1, a);
// Calling recursive function
// for zero
else
ans += recur(i + 1, 0, k, 0, a);
}
}
// If first non integer digit taken
else {
// Traversing from 0 to maxValue
for ( int digit = 0; digit <= maxValue; digit++) {
// Calling recursive function
// for maxValue digit and
// flipping l that is current
// position is odd or even and
// turn them into even or odd.
if (digit == maxValue)
ans += recur(i + 1, j,
k + (l == 1 ? -digit : digit),
l == 1 ? 2 : 1, a);
// Calling recursive function
// for non max value digit and
// flipping l that is current
// position is odd or even and
// turn them into even or odd
else
ans += recur(i + 1, 0,
k + (l == 1 ? -digit : digit),
l == 1 ? 2 : 1, a);
}
}
// Save and return dp value
return dp[i][j][k + 180][l] = ans;
} // Function to find numbers // summation of f(x) in the range L to R int findfxfromLtoR( int A, int B)
{ // Initializing dp array with - 1
memset (dp, -1, sizeof (dp));
A--;
string L = to_string(A), R = to_string(B);
// f(x) for the range 0 to L
int ans1 = recur(0, 1, 0, 0, L);
// Initializing dp array with - 1
memset (dp, -1, sizeof (dp));
// f(x) for the range 0 to R
int ans2 = recur(0, 1, 0, 0, R);
// Difference of ans2 and ans1
// will generate answer for required range
return ans2 - ans1;
} // Driver Code int main()
{ // Input 1
int L = 10, R = 15;
// Function Call
cout << findfxfromLtoR(L, R) << endl;
// Input 2
int L1 = 101, R1 = 105;
// Function Call
cout << findfxfromLtoR(L1, R1) << endl;
return 0;
} |
// Java code to implement the approach import java.io.*;
import java.util.*;
class GFG {
// DP table initialized with -1
static int [][][][] dp = new int [ 200 ][ 20 ][ 500 ][ 20 ];
// Recursive Function to find numbers
// summation of f(x) in the range L to R
public static int recur( int i, int j, int k, int l,
String a)
{
// Base case
if (i == a.length()) {
return k;
}
// If answer for current state is already calculated
// then just return dp[i][j][k][l] +180 is offset to
// store negative values
if (dp[i][j][k + 180 ][l] != - 1 )
return dp[i][j][k + 180 ][l];
// Answer initialized with zero
int ans = 0 ;
// MaxValue that can be traversed
int maxValue = j == 1 ? a.charAt(i) - 48 : 9 ;
// If first non integer digit not taken
if (l == 0 ) {
// Traversing from 0 to maxValue
for ( int digit = 0 ; digit <= maxValue;
digit++) {
// Calling recursive function
// for maxValue digit
if (digit == maxValue)
ans += recur(i + 1 , j, k + digit, 1 , a);
// Calling recursive function
// for non-zero digit
else if (digit != 0 )
ans += recur(i + 1 , 0 , k + digit, 1 , a);
// Calling recursive function
// for zero
else
ans += recur(i + 1 , 0 , k, 0 , a);
}
}
// If first non integer digit taken
else {
// Traversing from 0 to maxValue
for ( int digit = 0 ; digit <= maxValue;
digit++) {
// Calling recursive function
// for maxValue digit and
// flipping l that is current
// position is odd or even and
// turn them into even or odd.
if (digit == maxValue) {
ans += recur(
i + 1 , j,
k + (l == 1 ? -digit : digit),
l == 1 ? 2 : 1 , a);
}
// Calling recursive function
// for non max value digit and
// flipping l that is current
// position is odd or even and
// turn them into even or odd
else
ans += recur(
i + 1 , 0 ,
k + (l == 1 ? -digit : digit),
l == 1 ? 2 : 1 , a);
}
}
// Save and return dp value
return dp[i][j][k + 180 ][l] = ans;
}
// Function to find numbers
// summation of f(x) in the range L to R
public static int findfxfromLtoR( int A, int B)
{
// Initializing dp array with - 1
for ( int [][][] dp1 : dp) {
for ( int [][] dp2 : dp1) {
for ( int [] dp3 : dp2) {
Arrays.fill(dp3, - 1 );
}
}
}
A--;
String L = Integer.toString(A);
String R = Integer.toString(B);
// f(x) for the range 0 to L
int ans1 = recur( 0 , 1 , 0 , 0 , L);
// Initializing dp array with - 1
for ( int [][][] dp1 : dp) {
for ( int [][] dp2 : dp1) {
for ( int [] dp3 : dp2) {
Arrays.fill(dp3, - 1 );
}
}
}
// f(x) for the range 0 to R
int ans2 = recur( 0 , 1 , 0 , 0 , R);
// Difference of ans2 and ans1
// will generate answer for required range
return ans2 - ans1;
}
public static void main(String[] args)
{
// Input 1
int L = 10 , R = 15 ;
// Function Call
System.out.println(findfxfromLtoR(L, R));
// Input 2
int L1 = 101 , R1 = 105 ;
// Function Call
System.out.println(findfxfromLtoR(L1, R1));
}
} // This code is contributed by lokesh. |
# DP table initialized with -1 dp = [[[[ - 1 for _ in range ( 2 )] for _ in range ( 360 )] for _ in range ( 2 )] for _ in range ( 20 )]
# Recursive Function to find numbers # summation of f(x) in the range L to R def recur(i, j, k, l, a):
# Base case
if i = = len (a):
return k
# If answer for current state is
# already calculated then just return
# dp[i][j][k][l] +180 is offset to
# store negative values
if dp[i][j][k + 180 ][l] ! = - 1 :
return dp[i][j][k + 180 ][l]
# Answer initialized with zero
ans = 0
# MaxValue that can be traversed
maxValue = int (a[i]) if j = = 1 else 9
# If first non integer digit
# not taken
if l = = 0 :
# Traversing from 0 to maxValue
for digit in range (maxValue + 1 ):
# Calling recursive function
# for maxValue digit
if digit = = maxValue:
ans + = recur(i + 1 , j, k + digit, 1 , a)
# Calling recursive function
# for non-zero digit
elif digit ! = 0 :
ans + = recur(i + 1 , 0 , k + digit, 1 , a)
# Calling recursive function
# for zero
else :
ans + = recur(i + 1 , 0 , k, 0 , a)
# If first non integer digit taken
else :
# Traversing from 0 to maxValue
for digit in range (maxValue + 1 ):
# Calling recursive function
# for maxValue digit and
# flipping l that is current
# position is odd or even and
# turn them into even or odd.
if digit = = maxValue:
ans + = recur(i + 1 , j, (k - digit if l = = 1 else k + digit), 2 if l = = 1 else 1 , a)
# Calling recursive function
# for non max value digit and
# flipping l that is current
# position is odd or even and
# turn them into even or odd
else :
ans + = recur(i + 1 , 0 , (k - digit if l = = 1 else k + digit), 2 if l = = 1 else 1 , a)
# Save and return dp value
dp[i][j][k + 180 ][l] = ans
return ans
# Function to find numbers # summation of f(x) in the range L to R def findfxfromLtoR(A, B):
A - = 1
L = str (A)
R = str (B)
# f(x) for the range 0 to L
ans1 = recur( 0 , 1 , 0 , 0 , L)
# Initializing dp array with - 1
dp = [[[[ - 1 for _ in range ( 2 )] for _ in range ( 360 )] for _ in range ( 2 )] for _ in range ( 20 )]
# f(x) for the range 0 to R
ans2 = recur( 0 , 1 , 0 , 0 , R)
# Difference of ans2 and ans1
# will generate answer for required range
return ans2 - ans1
# Driver Code if __name__ = = '__main__' :
# Input 1
L = 10
R = 15
# Function Call
print (findfxfromLtoR(L, R))
# Input 2
L1 = 101
R1 = 105
# Function Call
print (findfxfromLtoR(L1, R1))
# This code is contributed by lokeshpotta20. |
// C# implementation of the above approach using System;
using System.Collections.Generic;
class GFG {
// DP table initialized with -1
static int [ , , ,] dp= new int [200, 20, 500, 20];
// Recursive Function to find numbers
// summation of f(x) in the range L to R
static int recur( int i, int j, int k, int l, string a)
{
// Base case
if (i == a.Length) {
return k;
}
// If answer for current state is
// already calculated then just return
// dp[i][j][k][l] +180 is offset to
// store negative values
if (dp[i,j,k + 180,l] != -1)
return dp[i,j,k + 180,l];
// Answer initialized with zero
int ans = 0;
// MaxValue that can be traversed
int maxValue = j == 1 ? a[i] - 48 : 9;
// If first non integer digit
// not taken
if (l == 0) {
// Traversing from 0 to maxValue
for ( int digit = 0; digit <= maxValue; digit++) {
// Calling recursive function
// for maxValue digit
if (digit == maxValue)
ans += recur(i + 1, j, k + digit, 1, a);
// Calling recursive function
// for non-zero digit
else if (digit != 0)
ans += recur(i + 1, 0, k + digit, 1, a);
// Calling recursive function
// for zero
else
ans += recur(i + 1, 0, k, 0, a);
}
}
// If first non integer digit taken
else {
// Traversing from 0 to maxValue
for ( int digit = 0; digit <= maxValue; digit++) {
// Calling recursive function
// for maxValue digit and
// flipping l that is current
// position is odd or even and
// turn them into even or odd.
if (digit == maxValue)
ans += recur(i + 1, j,
k + (l == 1 ? -digit : digit),
l == 1 ? 2 : 1, a);
// Calling recursive function
// for non max value digit and
// flipping l that is current
// position is odd or even and
// turn them into even or odd
else
ans += recur(i + 1, 0,
k + (l == 1 ? -digit : digit),
l == 1 ? 2 : 1, a);
}
}
// Save and return dp value
return dp[i,j,k + 180,l] = ans;
}
// Function to find numbers
// summation of f(x) in the range L to R
static int findfxfromLtoR( int A, int B)
{
// Initializing dp array with - 1
for ( int i=0; i<200; i++)
{
for ( int j=0; j<20; j++)
{
for ( int k=0; k<500; k++)
{
for ( int l=0; l<20; l++)
dp[i,j,k,l]=-1;
}
}
}
A--;
string L = A.ToString(), R = B.ToString();
// f(x) for the range 0 to L
int ans1 = recur(0, 1, 0, 0, L);
// Initializing dp array with - 1
for ( int i=0; i<200; i++)
{
for ( int j=0; j<20; j++)
{
for ( int k=0; k<500; k++)
{
for ( int l=0; l<20; l++)
dp[i,j,k,l]=-1;
}
}
}
// f(x) for the range 0 to R
int ans2 = recur(0, 1, 0, 0, R);
// Difference of ans2 and ans1
// will generate answer for required range
return ans2 - ans1;
}
// Driver Code
public static void Main()
{
// Input 1
int L = 10, R = 15;
// Function Call
Console.WriteLine(findfxfromLtoR(L, R));
// Input 2
int L1 = 101, R1 = 105;
// Function Call
Console.WriteLine(findfxfromLtoR(L1, R1));
}
} // This code is contributed by poojaagarwal2. |
// JavaScript code to implement the approach // DP table initialized with -1 let dp = new Array(200);
for (let i = 0; i < 200; i++) {
dp[i] = new Array(20);
for (let j = 0; j < 20; j++) {
dp[i][j] = new Array(500);
for (let k = 0; k < 500; k++) {
dp[i][j][k] = new Array(20).fill(-1);
}
}
} // Recursive Function to find numbers // summation of f(x) in the range L to R function recur(i, j, k, l, a)
{ // Base case
if (i === a.length) {
return k;
}
// If answer for current state is already calculated
// then just return dp[i][j][k][l] +180 is offset to
// store negative values
if (dp[i][j][k + 180][l] !== -1) {
return dp[i][j][k + 180][l];
}
// Answer initialized with zero
let ans = 0;
// MaxValue that can be traversed
let maxValue = j === 1 ? Number(a[i]) : 9;
// If first non integer digit not taken
if (l === 0) {
// Traversing from 0 to maxValue
for (let digit = 0; digit <= maxValue; digit++) {
// Calling recursive function
// for maxValue digit
if (digit === maxValue) {
ans += recur(i + 1, j, k + digit, 1, a);
}
// Calling recursive function
// for non-zero digit
else if (digit !== 0) {
ans += recur(i + 1, 0, k + digit, 1, a);
}
// Calling recursive function
// for zero
else {
ans += recur(i + 1, 0, k, 0, a);
}
}
} else {
// Traversing from 0 to maxValue
for (let digit = 0; digit <= maxValue; digit++) {
// Calling recursive function
// for maxValue digit and
// flipping l that is current
// position is odd or even and
// turn them into even or odd.
if (digit === maxValue) {
ans += recur(i + 1, j, k + (l === 1 ? -digit : digit), l === 1 ? 2 : 1, a);
}
// Calling recursive function
// for non max value digit and
// flipping l that is current
// position is odd or even and
// turn them into even or odd
else {
ans += recur(i + 1, 0, k + (l === 1 ? -digit : digit), l === 1 ? 2 : 1, a);
}
}
}
// Save and return dp value
return dp[i][j][k + 180][l] = ans;
} // Function to find numbers summation of f(x) in the range L to R function findfxfromLtoR(A, B) {
// Initializing dp array with - 1
dp.forEach(dp1 => dp1.forEach(dp2 => dp2.forEach(dp3 => dp3.fill(-1))));
A--;
let L = A.toString();
let R = B.toString();
// f(x) for the range 0 to L
let ans1 = recur(0, 1, 0, 0, L);
// Initializing dp array with - 1
dp.forEach(dp1 => dp1.forEach(dp2 => dp2.forEach(dp3 => dp3.fill(-1))));
// f(x) for the range 0 to R
let ans2 = recur(0, 1, 0, 0, R);
// Difference of ans2 and ans1 will generate answer for required range
return ans2 - ans1;
} // Input 1 L = 10; R = 15; // Function call console.log(findfxfromLtoR(L, R) + "<br>" );
// Input 2 L1 = 101; R1 = 105; // Function call console.log(findfxfromLtoR(L1, R1)); // This code is contributed by lokeshmvs21. |
-9 20
Time Complexity: O(log(R – L) * M), where M is the maximum value of f(x)
Auxiliary Space: O(log(R – L) * M)
Related Articles: