Open In App

Distinct powers of a number N such that the sum is equal to K

Given two numbers N and K, the task is to print the distinct powers of N which are used to get the sum K. If it’s not possible, print -1.

Examples:  



Input: N = 3, K = 40 
Output: 0, 1, 2, 3 
Explanation: 
The value of N is 3. 
30 + 31 + 32 + 33 = 40

Input: N = 4, K = 65 
Output: 0, 3 
The value of N is 4. 
40 + 43 = 65



Input: N = 4, K = 18 
Output: -1 
Explanation: 
It’s impossible to get 18 by adding the power of 4.  

Observation: One observation that needs to be made for any arbitrary number a is that there can’t exist a number greater than aK if all the powers of a from 0 to k-1 are added by using each power at most once. 
 

Example: Let a = 3 and K = 4. Then:  

34 = 81. 
30 + 31 + 32 + 33 = 40 which is less than 81(34). 
 

Naive Approach: By using the above observation, the naive approach can be formed. The idea is to continuously subtract the highest power of N not exceeding K from K until K reaches 0. If at any instance, K becomes equal to some power that was already subtracted from it previously, then it’s not possible to get the sum equal to K. Therefore, an array is used to keep track of powers that have been subtracted from K. 

Below is the implementation of the above approach: 




// C++ implementation to find distinct
// powers of N that add upto K
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the highest power
// of N not exceeding K
int highestPower(int n, int k)
{
    int i = 0;
    int a = pow(n, i);
 
    // Loop to find the highest power
    // less than K
    while (a <= k) {
        i += 1;
        a = pow(n, i);
    }
    return i - 1;
}
 
// Initializing the PowerArray
// with all 0's.
int b[50] = { 0 };
 
// Function to print
// the distinct powers of N
// that add upto K
int PowerArray(int n, int k)
{
    while (k) {
 
        // Getting the highest
        // power of n before k
        int t = highestPower(n, k);
 
        // To check if the power
        // is being used twice or not
        if (b[t]) {
 
            // Print -1 if power
            // is being used twice
            cout << -1;
            return 0;
        }
 
        else
            // If the power is not visited,
            // then mark the power as visited
            b[t] = 1;
 
        // Decrementing the value of K
        k -= pow(n, t);
    }
 
    // Printing the powers of N
    // that sum up to K
    for (int i = 0; i < 50; i++) {
        if (b[i]) {
            cout << i << ", ";
        }
    }
}
 
// Driver code
int main()
{
    int N = 3;
    int K = 40;
    PowerArray(N, K);
    return 0;
}




// Java implementation to find distinct
// powers of N that add upto K
 
class GFG{
  
// Function to return the highest power
// of N not exceeding K
static int highestPower(int n, int k)
{
    int i = 0;
    int a = (int) Math.pow(n, i);
  
    // Loop to find the highest power
    // less than K
    while (a <= k) {
        i += 1;
        a = (int) Math.pow(n, i);
    }
    return i - 1;
}
  
// Initializing the PowerArray
// with all 0's.
static int b[] = new int[50];
  
// Function to print
// the distinct powers of N
// that add upto K
static int PowerArray(int n, int k)
{
    while (k>0) {
  
        // Getting the highest
        // power of n before k
        int t = highestPower(n, k);
  
        // To check if the power
        // is being used twice or not
        if (b[t]>0) {
  
            // Print -1 if power
            // is being used twice
            System.out.print(-1);
            return 0;
        }
  
        else
            // If the power is not visited,
            // then mark the power as visited
            b[t] = 1;
  
        // Decrementing the value of K
        k -= Math.pow(n, t);
    }
  
    // Printing the powers of N
    // that sum up to K
    for (int i = 0; i < 50; i++) {
        if (b[i] > 0) {
            System.out.print(i+ ", ");
        }
    }
    return 0;
}
  
// Driver code
public static void main(String[] args)
{
    int N = 3;
    int K = 40;
    PowerArray(N, K);
}
}
 
// This code contributed by Rajput-Ji




# Python 3 implementation to find distinct
# powers of N that add up to K
 
from math import pow
 
# Function to return the highest power
# of N not exceeding K
def highestPower(n,k):
    i = 0
    a = pow(n, i)
 
    # Loop to find the highest power
    # less than K
    while (a <= k):
        i += 1
        a = pow(n, i)
    return i - 1
 
# Initializing the PowerArray
# with all 0's.
b = [0 for i in range(50)]
 
# Function to print
# the distinct powers of N
# that add upto K
def PowerArray(n, k):
    while (k):
        # Getting the highest
        # power of n before k
        t = highestPower(n, k)
 
        # To check if the power
        # is being used twice or not
        if (b[t]):
            # Print -1 if power
            # is being used twice
            print(-1)
            return 0
 
        else:
            # If the power is not visited,
            # then mark the power as visited
            b[t] = 1
 
        # Decrementing the value of K
        k -= pow(n, t)
 
    # Printing the powers of N
    # that sum up to K
    for i in range(50):
        if (b[i]):
            print(i,end = ', ')
 
# Driver code
if __name__ == '__main__':
    N = 3
    K = 40
    PowerArray(N, K)
     
# This code is contributed by Surendra_Gangwar




     
// C# implementation to find distinct
// powers of N that add up to K
 
using System;
 
public class GFG{
 
// Function to return the highest power
// of N not exceeding K
static int highestPower(int n, int k)
{
    int i = 0;
    int a = (int) Math.Pow(n, i);
 
    // Loop to find the highest power
    // less than K
    while (a <= k) {
        i += 1;
        a = (int) Math.Pow(n, i);
    }
    return i - 1;
}
 
// Initializing the PowerArray
// with all 0's.
static int []b = new int[50];
 
// Function to print
// the distinct powers of N
// that add upto K
static int PowerArray(int n, int k)
{
    while (k > 0) {
 
        // Getting the highest
        // power of n before k
        int t = highestPower(n, k);
 
        // To check if the power
        // is being used twice or not
        if (b[t] > 0) {
 
            // Print -1 if power
            // is being used twice
            Console.Write(-1);
            return 0;
        }
 
        else
            // If the power is not visited,
            // then mark the power as visited
            b[t] = 1;
 
        // Decrementing the value of K
        k -= (int)Math.Pow(n, t);
    }
 
    // Printing the powers of N
    // that sum up to K
    for (int i = 0; i < 50; i++) {
        if (b[i] > 0) {
            Console.Write(i+ ", ");
        }
    }
    return 0;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 3;
    int K = 40;
    PowerArray(N, K);
}
}
 
// This code is contributed by 29AjayKumar




<script>
// Javascript implementation to find distinct
// powers of N that add upto K
 
// Function to return the highest power
// of N not exceeding K
function highestPower(n, k)
{
    let i = 0;
    let a = Math.pow(n, i);
  
    // Loop to find the highest power
    // less than K
    while (a <= k) {
        i += 1;
        a = Math.pow(n, i);
    }
    return i - 1;
}
  
// Initializing the PowerArray
// with all 0's.
let b = Array.from({length: 50}, (_, i) => 0);
  
// Function to print
// the distinct powers of N
// that add upto K
function PowerArray(n, k)
{
    while (k>0) {
  
        // Getting the highest
        // power of n before k
        let t = highestPower(n, k);
  
        // To check if the power
        // is being used twice or not
        if (b[t]>0) {
  
            // Print -1 if power
            // is being used twice
            document.write(-1);
            return 0;
        }
  
        else
            // If the power is not visited,
            // then mark the power as visited
            b[t] = 1;
  
        // Decrementing the value of K
        k -= Math.pow(n, t);
    }
  
    // Printing the powers of N
    // that sum up to K
    for (let i = 0; i < 50; i++) {
        if (b[i] > 0) {
            document.write(i+ ", ");
        }
    }
    return 0;
}
 
// Driver Code
     
    let N = 3;
    let K = 40;
    PowerArray(N, K);
         
</script>

Output: 
0, 1, 2, 3,

 

Time Complexity: O((log N)2)  

Auxiliary Space: O(50)

Efficient Approach: Another observation that can be made is that for K to be the sum of N’s powers which can be used only once, K % N either has to be 1 or 0 (1 because of N0). Therefore, if (K % N) comes out anything other than 0 or 1, it can be concluded that it is impossible to get the sum K.
Therefore, by using the above observations, the following steps can be followed to compute the answer:  

  1. First, a counter is initialized with 0.
  2. If (K % N) = 0, then the counter is incremented by 1, and K is updated to K/N.
  3. If K % N = 1, then the frequency array f[count] is incremented by 1, and K is updated to K – 1.
  4. If, at any point, this f[count] becomes more than 1, then return -1(because the same power can’t be used twice).

Below is the implementation of the above approach: 




// C++ implementation to find out
// the powers of N that add upto K
 
#include <bits/stdc++.h>
using namespace std;
 
// Initializing the PowerArray
// with all 0's
int b[50] = { 0 };
 
// Function to find the powers of N
// that add up to K
int PowerArray(int n, int k)
{
 
    // Initializing the counter
    int count = 0;
 
    // Executing the while
    // loop until K is
    // greater than 0
    while (k) {
        if (k % n == 0) {
            k /= n;
            count++;
        }
 
        // If K % N == 1,
        // then the power array
        // is incremented by 1
        else if (k % n == 1) {
            k -= 1;
            b[count]++;
 
            // Checking if any power is
            // occurred more than once
            if (b[count] > 1) {
                cout << -1;
                return 0;
            }
        }
 
        // For any other value, the sum of
        // powers cannot be added up to K
        else {
            cout << -1;
            return 0;
        }
    }
 
    // Printing the powers of N
    // that sum up to K
    for (int i = 0; i < 50; i++) {
        if (b[i]) {
            cout << i << ", ";
        }
    }
}
 
// Driver code
int main()
{
    int N = 3;
    int K = 40;
    PowerArray(N, K);
    return 0;
}




// Java implementation to find out
// the powers of N that add upto K
class GFG{
 
// Initializing the PowerArray
// with all 0's
static int b[] = new int[50];
 
// Function to find the powers of N
// that add up to K
static int PowerArray(int n, int k)
{
 
    // Initializing the counter
    int count = 0;
 
    // Executing the while
    // loop until K is
    // greater than 0
    while (k > 0)
    {
        if (k % n == 0)
        {
            k /= n;
            count++;
        }
 
        // If K % N == 1,
        // then the power array
        // is incremented by 1
        else if (k % n == 1)
        {
            k -= 1;
            b[count]++;
 
            // Checking if any power is
            // occurred more than once
            if (b[count] > 1)
            {
                System.out.print(-1);
                return 0;
            }
        }
 
        // For any other value, the sum of
        // powers cannot be added up to K
        else
        {
            System.out.print(-1);
            return 0;
        }
    }
 
    // Printing the powers of N
    // that sum up to K
    for(int i = 0; i < 50; i++)
    {
       if (b[i] != 0)
       {
           System.out.print(i + ", ");
       }
    }
    return Integer.MIN_VALUE;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 3;
    int K = 40;
    PowerArray(N, K);
}
}
 
// This code is contributed by Rajput-Ji




# Python3 implementation to find out
# the powers of N that add upto K
 
# Initializing the PowerArray
# with all 0's
b = [0 for i in range(50)]
 
# Function to find the powers of N
# that add up to K
def PowerArray(n, k):
     
    # Initializing the counter
    count = 0
 
    # Executing the while
    # loop until K is
    # greater than 0
    while (k):
        if (k % n == 0):
            k //= n
            count += 1
 
        # If K % N == 1,
        # then the power array
        # is incremented by 1
        elif (k % n == 1):
            k -= 1
            b[count] += 1
 
            # Checking if any power is
            # occurred more than once
            if (b[count] > 1):
                print(-1)
                return 0
 
        # For any other value, the sum of
        # powers cannot be added up to K
        else:
            print(-1)
            return 0
 
    # Printing the powers of N
    # that sum up to K
    for i in range(50):
        if (b[i]):
            print(i,end = ",")
 
# Driver code
if __name__ == '__main__':
     
    N = 3
    K = 40
     
    PowerArray(N, K)
     
# This code is contributed by ipg2016107




// C# implementation to find out
// the powers of N that add upto K
using System;
 
class GFG{
 
// Initializing the PowerArray
// with all 0's
static int []b = new int[50];
 
// Function to find the powers of N
// that add up to K
static int PowerArray(int n, int k)
{
 
    // Initializing the counter
    int count = 0;
 
    // Executing the while loop
    // until K is greater than 0
    while (k > 0)
    {
        if (k % n == 0)
        {
            k /= n;
            count++;
        }
 
        // If K % N == 1, then
        // the power array is
        // incremented by 1
        else if (k % n == 1)
        {
            k -= 1;
            b[count]++;
 
            // Checking if any power is
            // occurred more than once
            if (b[count] > 1)
            {
                Console.Write(-1);
                return 0;
            }
        }
 
        // For any other value, the sum of
        // powers cannot be added up to K
        else
        {
            Console.Write(-1);
            return 0;
        }
    }
 
    // Printing the powers of N
    // that sum up to K
    for(int i = 0; i < 50; i++)
    {
       if (b[i] != 0)
       {
           Console.Write(i + ", ");
       }
    }
    return int.MinValue;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 3;
    int K = 40;
     
    PowerArray(N, K);
}
}
 
// This code is contributed by Rohit_ranjan




<script>
    // Javascript implementation to find out
    // the powers of N that add upto K
     
    // Initializing the PowerArray
    // with all 0's
    let b = new Array(50);
    b.fill(0);
 
    // Function to find the powers of N
    // that add up to K
    function PowerArray(n, k)
    {
 
        // Initializing the counter
        let count = 0;
 
        // Executing the while loop
        // until K is greater than 0
        while (k > 0)
        {
            if (k % n == 0)
            {
                k = parseInt(k / n, 10);
                count++;
            }
 
            // If K % N == 1, then
            // the power array is
            // incremented by 1
            else if (k % n == 1)
            {
                k -= 1;
                b[count]++;
 
                // Checking if any power is
                // occurred more than once
                if (b[count] > 1)
                {
                    document.write(-1);
                    return 0;
                }
            }
 
            // For any other value, the sum of
            // powers cannot be added up to K
            else
            {
                document.write(-1);
                return 0;
            }
        }
 
        // Printing the powers of N
        // that sum up to K
        for(let i = 0; i < 50; i++)
        {
           if (b[i] != 0)
           {
               document.write(i + ", ");
           }
        }
        return Number.MIN_VALUE;
    }
     
    let N = 3;
    let K = 40;
      
    PowerArray(N, K);
 
</script>

Output: 
0, 1, 2, 3,

 

Time Complexity: Since the highest power is not checked every time, the running time of this algorithm is log(N).

Auxiliary Space: O(50)
 


Article Tags :