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
and so on…
- 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++
// 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 |
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) |
431
Time Complexity: O(logn)