CSES Solutions Digit Queries (original) (raw)

Last Updated : 28 Mar, 2024

Consider an **infinite string that consists of all positive integers in **increasing order: [12345678910111213141516171819202122232425...]. The task is to process **Q queries of the form: return the **N th digit of the infinite string sequence.

Example:

**Input: Q = 3, queries[] = {7, 19, 12}
**Output: 7 4 1
**Explanation:

**Input: Q = 2, queries[] = {92, 152}
**Output: 5 8
**Explanation:

**Approach: To solve the problem, follow the idea below:

The idea is to divide the problem in three parts:

Identify the interval in which the Nth digit is located by calculating the number of digits in each interval. For instance, there are 9 (1*9) digits in the interval 1 - 9, 180 (2*90) digits in the interval 10 - 99, 2700 (3*900) digits in the interval 100 - 999, and so on. Subtract N with the number of digits in the interval (base*digits) and stop if it is less than zero. Now to find the target number, we know that the first 'd' digit number would be 10^(d-1), adding (N-1)/d to it would give us our target number. Index of the Nth digit is N % d. If index equals to 0, it means the target digit is the last digit of number else divide the target number by 10^(digits - index) and return the last digit which is our result.

Step-by-step algorithm:

Below is the implementation of the above algorithm:

C++ `

#include <bits/stdc++.h> using namespace std;

// Function to calculate a^b using binary exponentiation long long power(long long a, long long b) { // If b = 0, whatever be the value of a, // our result will be 1. long long res = 1; while (b > 0) { // If b is an odd number, then // (a^b) = (a * (a^(b–1)/2)^2) if (b & 1) { res = (res * a); }

    // If b is an even number, then
    // (a^b) = ((a^2)^(b/2))
    a = (a * a);
    b >>= 1;
}
return res;

}

long long findDigit(long long int N) { // No of digits long long digits = 1; // Total numbers in current digit interval long long base = 9;

// Find the interval in which the Nth digit lies
while (N - digits * base > 0) {
    N -= digits * base;
    base *= 10;
    digits++;
}
long long index = N % digits;

// Calculate the number which contains the Nth digit
long long res
    = power(10, (digits - 1)) + (N - 1) / digits;

// Find out which digit in the number is the result
if (index != 0)
    res = res / power(10, digits - index);
return res % 10;

}

// Drive Code int main() { // Example 1 long long q = 3; int queries[q] = { 7, 19, 12 }; for (int i = 0; i < q; i++) cout << findDigit(queries[i]) << " ";

cout << endl;

return 0;

}

Java

public class Main {

// Function to calculate a^b using binary exponentiation
static long power(long a, long b) {
    // If b = 0, whatever be the value of a,
    // our result will be 1.
    long res = 1;
    while (b > 0) {
        // If b is an odd number, then
        // (a^b) = (a * (a^(b–1)/2)^2)
        if ((b & 1) == 1) {
            res = (res * a);
        }

        // If b is an even number, then
        // (a^b) = ((a^2)^(b/2))
        a = (a * a);
        b >>= 1;
    }
    return res;
}

static long findDigit(long N) {
    // No of digits
    long digits = 1;
    // Total numbers in the current digit interval
    long base = 9;

    // Find the interval in which the Nth digit lies
    while (N - digits * base > 0) {
        N -= digits * base;
        base *= 10;
        digits++;
    }
    long index = N % digits;

    // Calculate the number which contains the Nth digit
    long res = power(10, (digits - 1)) + (N - 1) / digits;

    // Find out which digit in the number is the result
    if (index != 0)
        res = res / power(10, digits - index);
    return res % 10;
}

// Drive Code
public static void main(String[] args) {
    // Example 1
    int q = 3;
    long[] queries = {7, 19, 12};
    for (int i = 0; i < q; i++)
        System.out.print(findDigit(queries[i]) + " ");

    System.out.println();
}

}

// This code is contributed by shivamgupta310570

Python

-- coding: utf-8 --

def power(a, b): # If b = 0, whatever be the value of a, # our result will be 1. res = 1 while b > 0: # If b is an odd number, then # (a^b) = (a * (a^(b–1)/2)^2) if b & 1: res *= a

    # If b is an even number, then
    # (a^b) = ((a^2)^(b/2))
    a *= a
    b >>= 1
return res

def find_digit(N): # No of digits digits = 1 # Total numbers in current digit interval base = 9

# Find the interval in which the Nth digit lies
while N - digits * base > 0:
    N -= digits * base
    base *= 10
    digits += 1
index = N % digits

# Calculate the number which contains the Nth digit
res = power(10, digits - 1) + (N - 1) // digits

# Find out which digit in the number is the result
if index != 0:
    res //= 10 ** (digits - index)
return res % 10

Driver Code

if name == "main": # Example 1 queries = [7, 19, 12] for query in queries: print find_digit(query), print

C#

using System;

public class Program { // Function to calculate a^b using binary exponentiation static long Power(long a, long b) { // If b = 0, whatever be the value of a, // our result will be 1. long res = 1; while (b > 0) { // If b is an odd number, then // (a^b) = (a * (a^(b–1)/2)^2) if ((b & 1) == 1) { res = (res * a); }

        // If b is an even number, then
        // (a^b) = ((a^2)^(b/2))
        a = (a * a);
        b >>= 1;
    }
    return res;
}

static long FindDigit(long N)
{
    // No of digits
    long digits = 1;
    // Total numbers in current digit interval
    long baseVal = 9;

    // Find the interval in which the Nth digit lies
    while (N - digits * baseVal > 0)
    {
        N -= digits * baseVal;
        baseVal *= 10;
        digits++;
    }
    long index = N % digits;

    // Calculate the number which contains the Nth digit
    long res = Power(10, (digits - 1)) + (N - 1) / digits;

    // Find out which digit in the number is the result
    if (index != 0)
        res = res / Power(10, digits - index);
    return res % 10;
}

// Drive Code
public static void Main()
{
    // Example 1
    int q = 3;
    long[] queries = { 7, 19, 12 };
    for (int i = 0; i < q; i++)
        Console.Write(FindDigit(queries[i]) + " ");

    Console.WriteLine();
}

}

JavaScript

// Function to calculate a^b using binary exponentiation function power(a, b) { // If b = 0, whatever be the value of a, // our result will be 1. let res = 1; while (b > 0) { // If b is an odd number, then // (a^b) = (a * (a^(b–1)/2)^2) if (b & 1) { res *= a; }

    // If b is an even number, then
    // (a^b) = ((a^2)^(b/2))
    a *= a;
    b >>= 1;
}
return res;

}

function findDigit(N) { // No of digits let digits = 1; // Total numbers in current digit interval let base = 9;

// Find the interval in which the Nth digit lies
while (N - digits * base > 0) {
    N -= digits * base;
    base *= 10;
    digits++;
}
let index = N % digits;

// Calculate the number which contains the Nth digit
let res = power(10, digits - 1) + Math.floor((N - 1) / digits);

// Find out which digit in the number is the result
if (index !== 0)
    res = Math.floor(res / power(10, digits - index));
return res % 10;

}

// Drive Code let q = 3; let queries = [7, 19, 12]; let output = ''; for (let i = 0; i < q; i++) output += findDigit(queries[i]) + " "; console.log(output);

`

**Time Complexity: O(Q * log(N)), where **Q is the number of queries and **N is the position of digit given in each query.
**Auxiliary Space: O(1)