Count of integers in a range which have even number of odd digits and odd number of even digits
Given a range [L, R], the task is to count the numbers which have even number of odd digits and odd number of even digits. For example,
- 8 has 1 even digit and 0 odd digit – Satisfies the condition since 1 is odd and 0 is even.
- 545 has 1 even digit and 2 odd digits – Satisfies the condition since 1 is odd and 2 is even.
- 4834 has 3 even digits and 1 odd digit – Does not satisfy the condition since there are odd numbers(i.e 1) of odd digits.
Examples:
Input: L = 1, R = 9
Output: 4
2, 4, 6 and 8 are the only integers from the
given range that satisfy the given conditions.Input: L = 1, R = 19
Output: 4Input: L = 123, R = 984
Output: 431
Approach:
- Case 1
There is a pattern in which these numbers occur betweenand
(where 1<=k<=18).
Number of occurrences from- 1 – 10 and 1 – 100 are 4
- 1 – 1000 and 1 – 10000 are 454
- 1 – 10000 and 1 – 100000 are 45454
- Case 2
- If the number of digits in a number is even then it cannot satisfy the given condition because we need an odd number(of digits) and an even number(of digits) to satisfy our condition and odd number + even number is always odd
- So if the number of digits for a given number(say n) is even then its number of occurrences from 1 is equal to the number of occurrences from
to largest
(1<=k<=18) which is less than n
Example:
Let n = 19, number of digits in 19 are 2
Therefore number of occurrences from 1 – 19 = number of occurrences from 1 – 10 (since 10 the largestless than 19)
- Case 3
If number of digits for a given number(say n) are odd then number of occurrences betweenand n is equal to
where is the largest
less than n.
Implementation: Now we now how to calculate the number of occurrences from 1 to given n. Therefore,
Number of occurrences from L to R = NumberOfOccurrencesUpto(R) – NumberOfOccurrencesUpto(L – 1) where L is not equal to 1.
Below is the implementation of the above approach:
C++14
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; #define ll long long // Pattern table from Case 1 map<ll, ll> values{{1, 0}, {10, 4}, {100, 4}, {1000, 454}, {10000, 454}, {100000, 45454}, {1000000, 45454}, {10000000, 4545454}, {100000000, 4545454}, {1000000000, 454545454}, {10000000000, 454545454}, {100000000000, 45454545454}, {1000000000000, 45454545454}, {10000000000000, 4545454545454}, {100000000000000, 4545454545454}, {1000000000000000, 454545454545454}, {10000000000000000, 454545454545454}, {100000000000000000, 45454545454545454}, {1000000000000000000, 45454545454545454}}; // Function that returns the number of // even and odd digits in val pair<ll, ll> count_even_odd(ll val) { ll even = 0, odd = 0; while (val) { ll num = val % 10; if (num % 2 == 0) even++; else odd++; val /= 10; } return make_pair(even, odd); } // Function that returns True if num // satisfies the given condition bool satisfies_condition(ll num) { pair<ll, ll> answer = count_even_odd(num); ll even = answer.first; ll odd = answer.second; if (even % 2 == 1 and odd % 2 == 0) return true ; return false ; } // Function to return the count of // numbers from 1 to val that // satisfies the given condition ll count_upto(ll val) { // If the value is already present // in the values dict if (values.find(val) != values.end()) return values[val]; ll index = 1; for ( int i = 0; i < to_string(val).length() - 1; i++) index *= 10; // If the value is even // Case 2 if (to_string(val).length() % 2 == 0) return values[index]; ll val_len = to_string(val).length(); ll cnt = values[index]; // Now the problem is to count the desired // numbers from 10**(val_len-1) + 1 to val ll left_end = index + 1; // Case 3 // Eliminating all the even numbers cnt += (val - left_end) / 2; if (satisfies_condition(val) or satisfies_condition(left_end)) cnt++; return cnt; } // Driver Code int main() { // Input l and r ll l = 123, r = 984; ll right = count_upto(r); ll left = 0; if (l == '1' ) left = 0; else left = count_upto(l - 1); cout << right - left << endl; return 0; } // This code is contributed by // sanjeev2552 |
Java
// Java implementation of the approach import java.io.*; import java.lang.*; import java.util.*; class GFG{ // Pattern table from Case 1 static HashMap<Long, Long> values = new HashMap<>(); public static void intitializeMap() { values = new HashMap<>(); values.put(1L, 0L); values.put(10L, 4L); values.put(100L, 4L); values.put(1000L, 454L); values.put(10000L, 454L); values.put(100000L, 45454L); values.put(1000000L, 45454L); values.put(10000000L, 4545454L); values.put(100000000L, 4545454L); values.put(1000000000L, 454545454L); values.put(10000000000L, 454545454L); values.put(100000000000L, 45454545454L); values.put(1000000000000L, 45454545454L); values.put(10000000000000L, 4545454545454L); values.put(100000000000000L, 4545454545454L); values.put(1000000000000000L, 454545454545454L); values.put(10000000000000000L, 454545454545454L); values.put(100000000000000000L, 45454545454545454L); values.put(1000000000000000000L, 45454545454545454L); } // Function that returns the number of // even and odd digits in val static long [] count_even_odd( long val) { long even = 0 , odd = 0 ; while (val > 0 ) { long num = val % 10 ; if (num % 2 == 0 ) even++; else odd++; val /= 10 ; } return ( new long [] { even, odd }); } // Function that returns True if num // satisfies the given condition static boolean satisfies_condition( long num) { long [] answer = count_even_odd(num); long even = answer[ 0 ]; long odd = answer[ 1 ]; if (even % 2 == 1 && odd % 2 == 0 ) return true ; return false ; } // Function to return the count of // numbers from 1 to val that // satisfies the given condition static long count_upto( long val) { // If the value is already present // in the values dict if (values.containsKey(val)) return values.get(val); long index = 1 ; for ( int i = 0 ; i < Long.toString(val).length() - 1 ; i++) index *= 10 ; // If the value is even // Case 2 if (Long.toString(val).length() % 2 == 0 ) return values.get(index); long val_len = Long.toString(val).length(); long cnt = values.get(index); // Now the problem is to count the desired // numbers from 10**(val_len-1) + 1 to val long left_end = index + 1 ; // Case 3 // Eliminating all the even numbers cnt += (val - left_end) / 2 ; if (satisfies_condition(val) || satisfies_condition(left_end)) cnt++; return cnt; } // Driver Code public static void main(String[] args) { // Input l and r long l = 123 , r = 984 ; // Function to initialize the Map intitializeMap(); long right = count_upto(r); long left = 0 ; if (l == '1' ) left = 0 ; else left = count_upto(l - 1 ); System.out.println(right - left); } } // This code is contributed by Kingash |
Python3
# Python3 implementation of the approach # Pattern table from Case 1 values = { 1 : 0 , 10 : 4 , 100 : 4 , 1000 : 454 , 10000 : 454 , 100000 : 45454 , 1000000 : 45454 , 10000000 : 4545454 , 100000000 : 4545454 , 1000000000 : 454545454 , 10000000000 : 454545454 , 100000000000 : 45454545454 , 1000000000000 : 45454545454 , 10000000000000 : 4545454545454 , 100000000000000 : 4545454545454 , 1000000000000000 : 454545454545454 , 10000000000000000 : 454545454545454 , 100000000000000000 : 45454545454545454 , 1000000000000000000 : 45454545454545454 , } # Function that returns the number of # even and odd digits in val def count_even_odd(val): even = odd = 0 while val > 0 : num = val % 10 if num % 2 = = 0 : even + = 1 else : odd + = 1 val / / = 10 return even, odd # Function that returns True if num # satisfies the given condition def satisfies_condition(num): even, odd = count_even_odd(num) if even % 2 = = 1 and odd % 2 = = 0 : return True return False # Function to return the count of numbers # from 1 to val that satisfies the given condition def count_upto(val): # If the value is already present in the # values dict if int (val) in values: return values[ int (val)] # If the value is even # Case 2 if len (val) % 2 = = 0 : return values[ int ( '1' + '0' * ( len (val) - 1 ))] val_len = len (val) count = values[ int ( '1' + '0' * (val_len - 1 ))] # Now the problem is to count the desired # numbers from 10**(val_len-1) + 1 to val left_end = int ( '1' + '0' * (val_len - 1 )) + 1 # Case 3 # Eliminating all the even numbers count + = ( int (val) - left_end) / / 2 if satisfies_condition( int (val)) or satisfies_condition(left_end): count + = 1 return count if __name__ = = '__main__' : # Input L and R ( as a string ) l, r = '123' , '984' right = count_upto(r) left = 0 if (l = = '1' ): left = 0 else : left = count_upto( str ( int (l) - 1 )) print (right - left) |
C#
// C# implementation of the approach using System; using System.Collections.Generic; class GFG{ // Pattern table from Case 1 static Dictionary< long , long > values = new Dictionary< long , long >(); public static void intitializeMap() { values = new Dictionary< long , long >(); values.Add(1L, 0L); values.Add(10L, 4L); values.Add(100L, 4L); values.Add(1000L, 454L); values.Add(10000L, 454L); values.Add(100000L, 45454L); values.Add(1000000L, 45454L); values.Add(10000000L, 4545454L); values.Add(100000000L, 4545454L); values.Add(1000000000L, 454545454L); values.Add(10000000000L, 454545454L); values.Add(100000000000L, 45454545454L); values.Add(1000000000000L, 45454545454L); values.Add(10000000000000L, 4545454545454L); values.Add(100000000000000L, 4545454545454L); values.Add(1000000000000000L, 454545454545454L); values.Add(10000000000000000L, 454545454545454L); values.Add(100000000000000000L, 45454545454545454L); values.Add(1000000000000000000L, 45454545454545454L); } // Function that returns the number of // even and odd digits in val static long [] count_even_odd( long val) { long even = 0, odd = 0; while (val > 0) { long num = val % 10; if (num % 2 == 0) even++; else odd++; val /= 10; } return ( new long []{ even, odd }); } // Function that returns True if num // satisfies the given condition static bool satisfies_condition( long num) { long [] answer = count_even_odd(num); long even = answer[0]; long odd = answer[1]; if (even % 2 == 1 && odd % 2 == 0) return true ; return false ; } // Function to return the count of // numbers from 1 to val that // satisfies the given condition static long count_upto( long val) { // If the value is already present // in the values dict if (values.ContainsKey(val)) return values[val]; long index = 1; for ( int i = 0; i < val.ToString().Length - 1; i++) index *= 10; // If the value is even // Case 2 if (val.ToString().Length % 2 == 0) return values[index]; long val_len = val.ToString().Length; long cnt = values[index]; // Now the problem is to count the desired // numbers from 10**(val_len-1) + 1 to val long left_end = index + 1; // Case 3 // Eliminating all the even numbers cnt += (val - left_end) / 2; if (satisfies_condition(val) || satisfies_condition(left_end)) cnt++; return cnt; } // Driver Code public static void Main(String[] args) { // Input l and r long l = 123, r = 984; // Function to initialize the Map intitializeMap(); long right = count_upto(r); long left = 0; if (l == '1' ) left = 0; else left = count_upto(l - 1); Console.WriteLine(right - left); } } // This code is contributed by umadevi9616 |
Javascript
<script> // JavaScript implementation of the approach // Pattern table from Case 1 let values = new Map(); values.set(1, 0) values.set(10, 4) values.set(100, 4) values.set(1000, 454) values.set(10000, 454) values.set(100000, 45454) values.set(1000000, 45454) values.set(10000000, 4545454) values.set(100000000, 4545454) values.set(1000000000, 454545454) values.set(10000000000, 454545454) values.set(100000000000, 45454545454) values.set(1000000000000, 45454545454) values.set(10000000000000, 4545454545454) values.set(100000000000000, 4545454545454) values.set(1000000000000000, 454545454545454) values.set(10000000000000000, 454545454545454) values.set(100000000000000000, 45454545454545454) values.set(1000000000000000000, 45454545454545454) // Function that returns the number of // even and odd digits in val function count_even_odd(val) { let even = 0, odd = 0; while (val) { let num = val % 10; if (num % 2 == 0) even++; else odd++; val = Math.floor(val/10); } return [even, odd]; } // Function that returns True if num // satisfies the given condition function satisfies_condition(num) { let answer = count_even_odd(num); let even = answer[0]; let odd = answer[1]; if (even % 2 == 1 && odd % 2 == 0) return true ; return false ; } // Function to return the count of // numbers from 1 to val that // satisfies the given condition function count_upto(val) { // If the value is already present // in the values dict if (values.has(val) == true ) return values.get(val); let index = 1; for (let i = 0;i < val.toString().length - 1;i++) index *= 10; // If the value is even // Case 2 if (val.toString().length % 2 == 0) return values.get(index); let val_len = Number.toString(val).length; let cnt = values.get(index); // Now the problem is to count the desired // numbers from 10**(val_len-1) + 1 to val let left_end = index + 1; // Case 3 // Eliminating all the even numbers cnt += Math.floor((val - left_end) / 2); if (satisfies_condition(val) || satisfies_condition(left_end)) cnt++; return cnt; } // Driver Code // Input l and r let l = 123, r = 984; let right = count_upto(r); let left = 0; if (l == '1' ) left = 0; else left = count_upto(l - 1); document.write(right - left); // This code is contributed by shinjanpatra </script> |
431
Time Complexity: O(logn)
Auxiliary Space: O(19*2)
Please Login to comment...