Open In App

Largest value of x such that axx is N-digit number of base b

Last Updated : 29 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given the integers a, b, N, the task is to find the largest number x such that a*x^{x}      is an N-digit number of base b.

Examples:  

Input: a = 2, b = 10, N = 2 
Output:
Explanation: 
Here 2 * 33 = 54, which has the number of digits = 2, 
but 2 * 44 = 512 which has a number of digits = 3, which is not equal to N. 
Therefore, the largest value of x is 2.

Input: a = 1, b = 2, N = 3 
Output:
Explanation: 
1 * 22 = 4 whose binary representation is 100 and it has 3 digits.  


Approach: This problem can be solved using binary search

  • The number of digits of ax^x      in base b      is \lceil\log_b{ax^x}\rceil    .
  • Binary search is used to find the largest x      such that the number of digits of ax^x      in base b      is exactly n    .
  • In binary search, we will check the number of digits ax^x    , where x = mid    , and change the pointer according to that. 
    \lceil\log_b{ax^x}\rceil = \lceil x*\log_b{x}+\log_b{a} \rceil

Below is the implementation of the above approach:

C++

// C++ implementation of the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find log_b(a)
double log(int a, int b)
{
    return log10(a) / log10(b);
}
 
int get(int a, int b, int n)
{
 
    // Set two pointer for binary search
    int lo = 0, hi = 1e6;
 
    int ans = 0;
 
    while (lo <= hi) {
        int mid = (lo + hi) / 2;
 
        // Calculating number of digits
        // of a*mid^mid in base b
        int dig = ceil((mid * log(mid, b)
                        + log(a, b)));
 
        if (dig > n) {
 
            // If number of digits > n
            // we can simply ignore it
            // and decrease our pointer
            hi = mid - 1;
        }
        else {
 
            // if number of digits <= n,
            // we can go higher to
            // reach value exactly equal to n
            ans = mid;
            lo = mid + 1;
        }
    }
 
    // return the largest value of x
    return ans;
}
 
// Driver Code
int main()
{
 
    int a = 2, b = 2, n = 6;
 
    cout << get(a, b, n)
         << "\n";
 
    return 0;
}

                    

Java

// Java implementation of the above approach
import java.util.*;
 
class GFG{
 
// Function to find log_b(a)
static int log(int a, int b)
{
    return (int)(Math.log10(a) /
                 Math.log10(b));
}
 
static int get(int a, int b, int n)
{
 
    // Set two pointer for binary search
    int lo = 0, hi = (int) 1e6;
 
    int ans = 0;
 
    while (lo <= hi)
    {
        int mid = (lo + hi) / 2;
 
        // Calculating number of digits
        // of a*mid^mid in base b
        int dig = (int) Math.ceil((mid * log(mid, b) +
                                         log(a, b)));
 
        if (dig > n)
        {
 
            // If number of digits > n
            // we can simply ignore it
            // and decrease our pointer
            hi = mid - 1;
        }
        else
        {
 
            // If number of digits <= n,
            // we can go higher to reach
            // value exactly equal to n
            ans = mid;
            lo = mid + 1;
        }
    }
 
    // Return the largest value of x
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    int a = 2, b = 2, n = 6;
 
    System.out.print(get(a, b, n) + "\n");
}
}
 
// This code is contributed by amal kumar choubey

                    

Python3

# Python3 implementation of the above approach
 
from math import log10,ceil,log
 
# Function to find log_b(a)
def log1(a,b):
    return log10(a)//log10(b)
 
def get(a,b,n):
    # Set two pointer for binary search
    lo = 0
    hi = 1e6
 
    ans = 0
 
    while (lo <= hi):
        mid = (lo + hi) // 2
 
        # Calculating number of digits
        # of a*mid^mid in base b
        dig = ceil((mid * log(mid, b) + log(a, b)))
 
        if (dig > n):
            # If number of digits > n
            # we can simply ignore it
            # and decrease our pointer
            hi = mid - 1
 
        else:
            # if number of digits <= n,
            # we can go higher to
            # reach value exactly equal to n
            ans = mid
            lo = mid + 1
 
    # return the largest value of x
    return ans
 
# Driver Code
if __name__ == '__main__':
    a = 2
    b = 2
    n = 6
 
    print(int(get(a, b, n)))
 
# This code is contributed by Surendra_Gangwar

                    

C#

// C# implementation of the above approach
using System;
class GFG{
 
// Function to find log_b(a)
static int log(int a, int b)
{
    return (int)(Math.Log10(a) /
                 Math.Log10(b));
}
 
static int get(int a, int b, int n)
{
 
    // Set two pointer for binary search
    int lo = 0, hi = (int) 1e6;
 
    int ans = 0;
 
    while (lo <= hi)
    {
        int mid = (lo + hi) / 2;
 
        // Calculating number of digits
        // of a*mid^mid in base b
        int dig = (int)Math.Ceiling((double)(mid *
                                         log(mid, b) +
                                         log(a, b)));
 
        if (dig > n)
        {
 
            // If number of digits > n
            // we can simply ignore it
            // and decrease our pointer
            hi = mid - 1;
        }
        else
        {
 
            // If number of digits <= n,
            // we can go higher to reach
            // value exactly equal to n
            ans = mid;
            lo = mid + 1;
        }
    }
 
    // Return the largest value of x
    return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
    int a = 2, b = 2, n = 6;
 
    Console.Write(get(a, b, n) + "\n");
}
}
 
// This code is contributed by amal kumar choubey

                    

Javascript

<script>
 
// Javascript implementation of the above approach
 
// Function to find log_b(a)
function log(a, b)
{
    return (Math.log10(a) /
                 Math.log10(b));
}
   
function get(a, b, n)
{
   
    // Set two pointer for binary search
    let lo = 0, hi = 1e6;
   
    let ans = 0;
   
    while (lo <= hi)
    {
        let mid = Math.floor((lo + hi) / 2);
   
        // Calculating number of digits
        // of a*mid^mid in base b
        let dig =  Math.ceil((mid * log(mid, b) +
                                         log(a, b)));
   
        if (dig > n)
        {
   
            // If number of digits > n
            // we can simply ignore it
            // and decrease our pointer
            hi = mid - 1;
        }
        else
        {
   
            // If number of digits <= n,
            // we can go higher to reach
            // value exactly equal to n
            ans = mid;
            lo = mid + 1;
        }
    }
   
    // Return the largest value of x
    return ans;
}
// Driver Code
     
    let a = 2, b = 2, n = 6;
   
    document.write(get(a, b, n) + "\n");
                       
</script>

                    

Output: 
3

 

Time Complexity: O(log(k)) where k=1e6.
Auxiliary Space: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads