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 powers of 4.



Observation: One observation which needs to be made for any arbitrary number a is that there cant exist a number greater than aK if all the powers of a from 0 to k-1 are added by using each power atmost 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 which 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 a track of powers that have been subtracted from K.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

      
// 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

chevron_right


Output:

0, 1, 2, 3,

Time Complexity: O((log N)2)

  • Time taken to find out the power is Log(N).
  • On top of that, another Log(N) loop is being used for K.
  • So, the overall time complexity is Log(N)2

Efficient Approach: Another observation which 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 observation, 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] comes more than 1, then return -1(because same power cant be used twice).

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


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).

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.